検索

JavaScript のイベント フローの概要

無料学習の推奨事項: js ビデオ チュートリアル

# #JavaScript イベント フローについて

##前書き
  • #本文
  • #イベントとは何ですか?
    • イベントとは何ですか?イベント ストリーミング?
    • イベント バブリングとイベント キャプチャ
    • DOM イベント階層
    • DOM0 イベント
    • DOM2 イベント
    結論
まえがき

この記事を読む前に、JavaScript イベント ループについて見てみることをお勧めします。もちろん、既に知っている人向けです。必要ありません! この記事では、js のイベント フローについて説明します。

#本文

Web ページ上でクリックやスライドなどの特定の種類の操作を実行すると、対応するイベントがトリガーされることは誰もが知っています。 。また、Web ページ全体が実際にはブラウザーによって DOM ツリーに解析されることもわかっています。ノードがイベントを生成すると、そのイベントはノードとルート ノードの間で一定の順序で伝播され、この伝播経路を通過するすべてのノードがイベントを受信します。このプロセス全体を DOM イベント フロー ## と呼びます#。

イベントとは何ですか?

js と html 間のやり取りは、実際には「イベント」を通じて実現されます。 Web ページ上のすべてのユーザーのクリック、選択、スライドなどは、JS の世界ではすべてイベントです。 イベントの場合、イベントが発生するとレスポンスが必要ですが、js ではいわゆるレスポンスがリスナーです。オブザーバー パターンと同様に、イベントはサブジェクトであり、イベントが発生すると、イベント (サブジェクト) に対応するすべてのリスナーに、対応する応答を実行するように通知する必要があります。

イベント フローとは何ですか?

イベント フローは、ページからイベントを受け取る順序を記述します。主に次の 2 種類に分かれます。

IE のイベント バブリング

Netscape のイベント キャプチャ
  • イベント バブリング vs イベント キャプチャ

IE が提案するイベント フロー モデルはイベント バブリングです。つまり、イベントは下から上に、ターゲットによってトリガーされた要素からドキュメント オブジェクトに至るまで、段階的に上向きに伝播します。

Netscape が提案したイベント フロー モデルはイベント キャプチャであり、イベント バブリングとは逆に、上から下へ、つまりドキュメント オブジェクトからターゲット オブジェクトのステップに伝播します。一歩ずつ。

上記は、DOM0 標準におけるイベント フローの仕組みです。その後、ECMAScript によって DOM2 のイベント フローがさらに標準化されました。 DOM2 では、イベントに含まれるイベント ストリームは次の 3 つのステージに分割されます。

イベント キャプチャ ステージ (capture)

ターゲット ステージ (target)
  1. イベントのバブリング段階 (バブル)

  2. DOM イベントの分類

DOM ノードでイベントが発生したときは、当然のことながら、次のことを行う必要があります。

このうち、より重要なものは DOM0/DOM2 であるため、以下ではそれらに焦点を当てて説明します。


DOM0 イベント

DOM0 レベルのイベントを実装するには、主に 2 つの方法があります。1 つ目は、関数名をイベント属性として直接使用するインライン モデルです。 htmlタグの属性値。次のとおりです:

// js code// eventDOM.jsfunction btnClick() {
    console.log('Hello World')}
<!-- html code -->
    
        <title>eventDOM demo</title>
    
    
        <p></p>
        <script></script>
    
ただし、インライン モデルには明らかな欠点があります。つまり、コンテンツ (html) と動作 (js) の分離に関する W3C 要件に違反しています。 2 番目のタイプは、スクリプト モデル (動的バインディング モデル) です。具体的な方法は、js スクリプトを通じて特定の DOM ノードを選択し、そのノードにイベント属性と属性値を追加します。次のように:

// js code// eventDOM.jslet btn = document.getElementById('btn')let btnClick = function() {
    console.log('Hello World')}btn.onclick = btnClick
<!-- html code -->
    
        <title>eventDOM demo</title>
    
    
        <p></p>
        <script></script>
    

をクリックすると、

Hello World

が表示されますが、問題ありません。上記の HTML コードに基づいて、次のように少し js を追加します:

// js code// eventDOM.jslet btn = document.getElementById('btn')let btnClick = function() {
    console.log('Hello World')}let btnClick2 = function() {
    console.log('Hello World again')}btn.onclick = btnClick
btn.onclick = btnClick2

これで、Hello World again をクリックした場合のみ表示されることがわかりました。したがって、スクリプト モデルでは、1 つのノードが同じタイプのイベントを 1 回追加することのみが許可され、後続のイベントは以前のイベントを上書きします。

最後に興味深い例を見てみましょう:<pre class="brush:php;toolbar:false">&lt;!-- html code --&gt;              &lt;title&gt;eventDOM demo&lt;/title&gt;                   &lt;p&gt;             btn3            &lt;/p&gt;&lt;p&gt;                 btn2                &lt;/p&gt;&lt;p&gt;                     btn1                &lt;/p&gt;             </pre>

                 <script></script>     
// js code// eventDOM.jslet btn1 = document.getElementById('btn1')let btn2 = document.getElementById('btn2')let btn3 = document.getElementById('btn3')btn1.onclick = function() {
    console.log('1')}btn2.onclick = function() {
    console.log('2')}btn3.onclick = function() {
    console.log('3')}

btn3 をクリックすると、出力は次のようになります:

これは期待どおりですが、btn1 をクリックするとどうなりますか? 出力は次のようになります:

これは少し奇妙です。btn1 には明らかに 1 つのリスナーを追加しただけですが、btn2 と btn3 と一緒に追加したように感じるのはなぜですか? 理由は、DOM0 には 2 つのモデルがあるためです: IE によって提案されたイベント バブリングと、 Netscape によって提案されたイベント キャプチャですが、実際には DOM0 はイベント バブリングのみをサポートしています。したがって、btn1 をクリックした場合のイベント フローは次のようになります。

つまり、イベント フローは btn2 と btn3 も通過するため、それらのイベント処理がトリガーされます。しかし、明らかに、これは私たちが望んでいる結果ではありません。

DOM2 イベント

さらに詳細に指定すると、DOM2 レベルのイベント ハンドラーが存在します。 2 つのメソッドが定義されています。

  • addEventListener() イベント リスナーの追加
  • removeEventListener() イベント リスナーの削除

これら 2 つの関数次の表:

#パラメータタイプ説明## eventscallbackuseCapture#Boolean(default:false)イベントがキャプチャフェーズで処理されるかどうか

DOM2 中就可以對同一個節點綁定兩個以上的同類型事件監聽器了,看看下面例子:

<!-- html code -->
    
        <title>eventDOM demo</title>
    
    
        <p></p>
        <script></script>
    
// js code// eventDOM.jslet btn = document.getElementById('btn')function hello() {
    console.log("Hello World")}function helloAgain() {
    console.log("Hello World again")}btn.addEventListener('click', hello, false)btn.addEventListener('click', helloAgain, false)

輸出如下:

解決了 DOM0 只能綁定一個同類型事件監聽器的缺點啦!值得注意的是,如果綁定同樣的監聽器兩次以上,仍然只會觸發一次。

再回到上面三個 p 的那個例子進行改寫如下:

<!-- html code -->
    
        <title>eventDOM demo</title>
    
    
        <p>
            btn3            </p><p>
                btn2                </p><p>
                    btn1                </p>
            
        
        <script></script>
    
// js code// eventDOM.jslet btn1 = document.getElementById('btn1')let btn2 = document.getElementById('btn2')let btn3 = document.getElementById('btn3')btn1.addEventListener('click', function() {
    console.log('1')}, true)btn2.addEventListener('click', function() {
    console.log('2')}, true)btn3.addEventListener('click', function() {
    console.log('3')}, true)

注意,這邊我們把 addEventListener 的第三個參數設為 true,也就是事件會在捕獲階段觸發。點擊 btn1 輸出如下:

看到順序與 DOM0 的順序反過來了。首先最外層(btn3)的節點先被觸發了,而因為第三個參數被設為 true,事件會在捕獲階段就被處理,所以輸出才會是 3,2,1。如果都是 false,就會是 1,2,3。

可見 DOM2 的事件處理機制有了更彈性的操作空間。我們也可以在不同階段綁定事件監聽器,看看下面例子:

<!-- 沿用上一段 html 代碼 -->
// js code// eventDOM.jsbtn1.addEventListener('click',function() {
    console.log('btn1 capture')}, true)btn1.addEventListener('click',function() {
    console.log('btn1 bubble')}, false)btn2.addEventListener('click',function() {
    console.log('btn2 capture')}, true)btn2.addEventListener('click',function() {
    console.log('btn2 bubble')}, false)btn3.addEventListener('click',function() {
    console.log('btn3 capture')}, true)btn3.addEventListener('click',function() {
    console.log('btn3 bubble')}, false)

點擊 btn1 輸出如下:

改變一下順序,如下:

<!-- 沿用上一段 html 代碼 -->
// js code// eventDOM.jsbtn1.addEventListener('click',function() {
    console.log('btn1 bubble')}, false)btn1.addEventListener('click',function() {
    console.log('btn1 capture')}, true)btn2.addEventListener('click',function() {
    console.log('btn2 bubble')}, false)btn2.addEventListener('click',function() {
    console.log('btn2 capture')}, true)btn3.addEventListener('click',function() {
    console.log('btn3 bubble')}, false)btn3.addEventListener('click',function() {
    console.log('btn3 capture')}, true)

點擊 btn1 輸出如下:

注意 btn1 的輸出。雖然捕獲階段先發生了,但是因為 btn1 本身就是目標節點,所以在這種情況下,總結出規律:在目標元素上不區分冒泡還是捕獲,是根據腳本中的順序來執行。

有時候,我們希望對於某節點,不要再經過冒泡階段了,DOM2 也提供了相應函數,stopPropagation

<!-- 沿用上一段 html 代碼 -->
// js code// eventDOM.jsbtn1.addEventListener('click',function() {
    console.log('btn1 capture')}, true)btn1.addEventListener('click',function() {
    console.log('btn1 bubble')}, false)btn2.addEventListener('click',function(e) {
    e.stopPropagation()
    console.log('btn2 capture')}, true)btn2.addEventListener('click',function() {
    console.log('btn2 bubble')}, false)btn3.addEventListener('click',function() {
    console.log('btn3 capture')}, true)btn3.addEventListener('click',function() {
    console.log('btn3 bubble')}, false)

點擊 btn1 輸出如下:

可以看到,因為我們在 btn2 的捕獲階段就阻止了 btn2 的冒泡階段,所以 btn2 在捕獲後就不再繼續執行下去,確保不會冒泡,事件流如下:

加強一下前面提到的知識點,如果是在 btn1 阻止冒泡,會變成怎樣呢?

<!-- 沿用上一段 html 代碼 -->
// js code// eventDOM.jsbtn1.addEventListener('click',function(e) {
    e.stopPropagation()
    console.log('btn1 capture')}, true)btn1.addEventListener('click',function() {
    console.log('btn1 bubble')}, false)btn2.addEventListener('click',function() {
    console.log('btn2 capture')}, true)btn2.addEventListener('click',function() {
    console.log('btn2 bubble')}, false)btn3.addEventListener('click',function() {
    console.log('btn3 capture')}, true)btn3.addEventListener('click',function() {
    console.log('btn3 bubble')}, false)

點擊 btn1 輸出如下:

雖然我們對 btn1 阻止了冒泡,但是為什麼還是輸出了 btn bubble呢?原因就是前面提到了,目標節點不區分 捕獲/冒泡 階段,但是後面也就不會繼續冒泡了,算是個比較特殊的情況,可以稍微留意下。

結語

本篇大致介紹了 js 的事件流的各種模型以及階段上的工作任務,個人認為應該還算詳細。雖然個人感覺好像對編程本身沒有太明顯的幫助,但是還是算是 js 的一個重要的知識點,學習下也沒甚麼不好。若內容有誤,還歡迎指點!

相关免费学习推荐:javascript(视频)

String 「クリック」など、監視するイベントの名前。ここで「on」にする必要はないことに注意してください。
function イベントをトリガーするために実行されるコールバック関数

以上がJavaScript のイベント フローの概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事はCSDNで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
C/CからJavaScriptへ:すべてがどのように機能するかC/CからJavaScriptへ:すべてがどのように機能するかApr 14, 2025 am 12:05 AM

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

JavaScriptエンジン:実装の比較JavaScriptエンジン:実装の比較Apr 13, 2025 am 12:05 AM

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

ブラウザを超えて:現実世界のJavaScriptブラウザを超えて:現実世界のJavaScriptApr 12, 2025 am 12:06 AM

現実世界におけるJavaScriptのアプリケーションには、サーバー側のプログラミング、モバイルアプリケーション開発、モノのインターネット制御が含まれます。 2。モバイルアプリケーションの開発は、ReactNativeを通じて実行され、クロスプラットフォームの展開をサポートします。 3.ハードウェアの相互作用に適したJohnny-Fiveライブラリを介したIoTデバイス制御に使用されます。

next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)Apr 11, 2025 am 08:23 AM

私はあなたの日常的な技術ツールを使用して機能的なマルチテナントSaaSアプリケーション(EDTECHアプリ)を作成しましたが、あなたは同じことをすることができます。 まず、マルチテナントSaaSアプリケーションとは何ですか? マルチテナントSaaSアプリケーションを使用すると、Singの複数の顧客にサービスを提供できます

next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)Apr 11, 2025 am 08:22 AM

この記事では、許可によって保護されたバックエンドとのフロントエンド統合を示し、next.jsを使用して機能的なedtech SaaSアプリケーションを構築します。 FrontEndはユーザーのアクセス許可を取得してUIの可視性を制御し、APIリクエストがロールベースに付着することを保証します

JavaScript:Web言語の汎用性の調査JavaScript:Web言語の汎用性の調査Apr 11, 2025 am 12:01 AM

JavaScriptは、現代のWeb開発のコア言語であり、その多様性と柔軟性に広く使用されています。 1)フロントエンド開発:DOM操作と最新のフレームワーク(React、Vue.JS、Angularなど)を通じて、動的なWebページとシングルページアプリケーションを構築します。 2)サーバー側の開発:node.jsは、非ブロッキングI/Oモデルを使用して、高い並行性とリアルタイムアプリケーションを処理します。 3)モバイルおよびデスクトップアプリケーション開発:クロスプラットフォーム開発は、反応および電子を通じて実現され、開発効率を向上させます。

JavaScriptの進化:現在の傾向と将来の見通しJavaScriptの進化:現在の傾向と将来の見通しApr 10, 2025 am 09:33 AM

JavaScriptの最新トレンドには、TypeScriptの台頭、最新のフレームワークとライブラリの人気、WebAssemblyの適用が含まれます。将来の見通しは、より強力なタイプシステム、サーバー側のJavaScriptの開発、人工知能と機械学習の拡大、およびIoTおよびEDGEコンピューティングの可能性をカバーしています。

javascriptの分解:それが何をするのか、なぜそれが重要なのかjavascriptの分解:それが何をするのか、なぜそれが重要なのかApr 09, 2025 am 12:07 AM

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境