ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript でのイベントのバブリングとキャプチャの詳細については、こちらをご覧ください。

JavaScript でのイベントのバブリングとキャプチャの詳細については、こちらをご覧ください。

青灯夜游
青灯夜游転載
2022-08-04 21:01:082528ブラウズ

この記事では、イベントのバブリングとキャプチャについて説明し、JS イベント ターゲットの検索方法 (バブリングとキャプチャ)、イベント プロキシ、e.target と e.currentTarget の違い、バブリングとキャプチャの防止、キャンセルについて理解できるようにします。デフォルトのイベントです。皆さんのお役に立てば幸いです!

1. EventTarget イベント ターゲットの検索方法 (バブルとキャプチャ)

イベント ターゲットとは、イベントがバインドされている要素 elemet を指します。 .addEventListener('click',function(){}) ここの要素はイベント ターゲットです。

#バブリングとキャプチャ:

  • #バブル イベント:

    イベントはデフォルトで下から上にバブリング実行されます。クリック イベントを例に挙げると、子要素をクリックすると、親要素以降のクリック イベントもトリガーできます。イベントの実行順序は下から上、つまりバブリング イベントです。
  • イベントのキャプチャ:

    もちろん、トップダウンのキャプチャ方法もあります。引き続きクリック イベントを例に挙げると、子要素がクリック イベントにバインドされ、その子要素をクリックすると、親要素およびその上の要素にバインドされたクリック イベントも実行されます。イベントの実行順序は上から下、つまりキャプチャ イベントです。
addEventListener(type,listener,useCapture) 単純な分析:

type: イベント タイプ

    listener: イベントリスニング処理関数
  • useCapture: イベントの検索方法を設定
  • false、バブリングイベント (デフォルト値)
    • true、イベントをキャプチャ
パラメータの使用キャプチャ分析:

重要なポイント! !イベント ターゲットをトリガーするプロセス全体は 2 つの段階 (キャプチャとバブリング) に分かれています。 useCapture この値は、イベント ターゲットのトリガーがどの段階で実行されるかを決定します。

バブリングとキャプチャーのシーケンス分析:

JavaScript でのイベントのバブリングとキャプチャの詳細については、こちらをご覧ください。それがわかります。この図から、イベントが最初にキャプチャされ、次にイベントがバブルされることがわかります。イベント キャプチャは上から下に行われ (外部イベントが最初にトリガーされます)、イベント バブリングは下から上に行われます (内部イベントが最初にトリガーされます)。

    キャプチャのプロセスは非特異的から特異的であり、バブリングは特異的から非特異的です。
  • キャプチャが優先されます
  • が、バブリング イベントがデフォルトの配信方法です。これは、イベントがデフォルトでバブリング段階でトリガーされることを意味します。 ############ポイント! !イベントターゲットの探索は「バブル」と「キャプチャ」の2段階に分かれており、ステージによってイベントターゲットが発生する順番が異なります。ネストされた要素にキャプチャとバブルの両方が存在する場合、キャプチャが優先される必要があり、キャプチャ フェーズのイベントが実行された後、バブリング フェーズのイベントが実行されます。
  • コードのデモ:

        <div>
            这是div1
            <div>
                这是div2
                <div>这是div3</div>
            </div>
        </div>
        <script>
            let div1 = document.getElementById(&#39;div1&#39;);
            let div2 = document.getElementById(&#39;div2&#39;);
            let div3 = document.getElementById(&#39;div3&#39;);
            div1.addEventListener(&#39;click&#39;,function(){
                console.log("这是div1的点击事件");
            },false);
            div2.addEventListener(&#39;click&#39;,function(){
                console.log("这是div2的点击事件");
            },false);
            div3.addEventListener(&#39;click&#39;,function(){
                console.log("这是div3的点击事件");
            },false);
        </script>
    
    以下のコンソール結果からわかるように、div3 をクリックすると、ここにイベントが表示されます。バブリングフェーズ中に実行されます。

[div3] をクリックしたまま、

div1.addEventListener

の 3 番目のパラメータを true に変更します。以下に示すように、div1 が最初に実行され、キャプチャが行われたことを示します。バブリングフェーズを優先します。

JavaScript でのイベントのバブリングとキャプチャの詳細については、こちらをご覧ください。

これを読んだ後は、必ず入力してください。すべての状況をリストしたわけではありません。残りの状況は、要約してみるために残しておきます (これだけで十分です)上記を理解してください。実際のコーディングはそれほど複雑ではありません)。 上記は、イベント ターゲット検索の 2 つのメカニズム

Bubbles

JavaScript でのイベントのバブリングとキャプチャの詳細については、こちらをご覧ください。Capture

についての私の理解です。

2. イベント プロキシ メカニズム (イベント委任)

イベント バブリングを使用してイベント プロキシ メカニズムを完成させます:


        
  • 列表1
  •     
  • 列表2

クリック イベントを上記のリストの

li にバインドする必要がある場合、クリックして li のコンテンツを取得します。通常、要素をトラバースしてクリック イベントをバインドします。

let lis = document.querySelectorAll('li');
for (let i = 0; i 
ノードが 10,000 個ある場合、上記の方法を使用して 10,000 個のイベントをバインドする必要があり、これはコードのパフォーマンスに大きな影響を与えます。したがって、バブリング メカニズムを使用して上記の問題を解決できます。つまり、イベントを親要素 ul

にバインドします。次のコードを見てください:

    
            
  • 列表1
  •         
  • 列表2
  •     
    <script> let ul = document.querySelector(&#39;ul&#39;); //我们可以通过事件对象(e)中的target属性可以访问到事件源(也就事件的触发元素) ul.addEventListener(&#39;click&#39;,function(e){ console.log(e.target.innerHTML); },false); </script> Event オブジェクト (e): addEventListener バインディング イベントであっても、直接の「.event name」であっても、イベント リスニング処理関数の最初のパラメーターは event です。物体###。イベント オブジェクトには、イベントに関する詳細情報が含まれます。たとえば、このオブジェクトには、

イベント ソース、イベント ID、イベント タイプ、イベント バインド要素、イベントがトリガーされたときのクリック位置などが含まれます。 このうち、e.target は、このイベントのトリガー元であるイベント ソースにアクセスできます。 <p><strong>既然能给父元素绑定事件监听,又能拿到触发的源头。所以我们通过“e.target”+“冒泡机制”就可以减少事件的绑定,能提升不少的性能。</strong></p> <p>依次点击列表1与列表2:</p> <p><img src="https://img.php.cn/upload/image/607/859/198/165961728965853JavaScript%20%E3%81%A7%E3%81%AE%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%AE%E3%83%90%E3%83%96%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%A8%E3%82%AD%E3%83%A3%E3%83%97%E3%83%81%E3%83%A3%E3%81%AE%E8%A9%B3%E7%B4%B0%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AF%E3%80%81%E3%81%93%E3%81%A1%E3%82%89%E3%82%92%E3%81%94%E8%A6%A7%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%E3%80%82" title="165961728965853JavaScript でのイベントのバブリングとキャプチャの詳細については、こちらをご覧ください。" alt="JavaScript でのイベントのバブリングとキャプチャの詳細については、こちらをご覧ください。"></p> <p><strong>总结:通过上面代码我们知道了“事件对象”+“冒泡机制”可以实现事件委托。事件委托就是当事件触发时,通过事件冒泡(或事件捕获)把要做的事委托给父元素来处理。</strong></p> <h2>三、e.target与e.currentTarget的区别:</h2> <ul> <li>e.target 指向的是触发事件监听的对象(事件源)。</li> <li>e.currentTarget 指向添加监听事件的对象(绑定事件的dom元素)。</li> </ul> <h2>四、阻止冒泡与捕获</h2> <p><strong><span style="font-size: 18px;">为什么要阻止冒泡或捕获?</span></strong></p> <p>点击当前元素时以冒泡的方式传递事件如果上级元素绑定了同样的事件,就会因为冒泡传递导致触发。同样捕获的过程中,也会触发与当前元素绑定的相同事件的上级。只是触发顺序不同。</p> <p>事件代理一般使用的冒泡,当然阻止冒泡一般不会影响事件代理,因为顺序问题只会影响捕获事件,这也是为什么都使用冒泡实现事件代理机制。</p> <p><strong><span style="font-size: 18px;">阻止冒泡或捕获的方法</span></strong></p> <p>这里我不考虑兼容性问题,我相信不久将来兼容性可以得到解决。</p> <p>阻止冒泡w3c推介的方法是event.stopPropagation(),顾名思义停止传播,他是事件对象(event)的方法,此方法是<code>阻止目标元素的继续冒泡(或捕获)

event.stopPropagation()阻止冒泡:

    <div>
        这是div1
        <div>
            这是div2
            <div>这是div3</div>
        </div>
    </div>
    <script>
        let div1 = document.getElementById(&#39;div1&#39;);
        let div2 = document.getElementById(&#39;div2&#39;);
        let div3 = document.getElementById(&#39;div3&#39;);
        div1.onclick = function (e) {
           alert(&#39;div1&#39;);
        }
        div2.onclick = function (e) {
           e.stopPropagation();
            alert(&#39;div2&#39;);
        }
        div3.onclick = function (e) {
           alert(&#39;div3&#39;);
        }
    </script>

上面代码默认都是冒泡事件,我们点击div3会依次弹出’div3’与’div2’,为什么没有弹出’div1’这是因为e.stopPropagation();阻止了目标元素的事件继续冒泡到上级。如果每个点击事件都加上了e.topPropagation就不会出现多弹窗的情况。

event.stopPropagation()阻止捕获:

    <div>
        这是div1
        <div>
            这是div2
            <div>这是div3</div>
        </div>
    </div>
    <script>
        let div1 = document.getElementById(&#39;div1&#39;);
        let div2 = document.getElementById(&#39;div2&#39;);
        let div3 = document.getElementById(&#39;div3&#39;);
        div1.addEventListener(&#39;click&#39;,function(e){
           	console.log(&#39;div1&#39;);
        },true);
        div2.addEventListener(&#39;click&#39;,function(e){
            console.log(&#39;div2&#39;);
            e.stopPropagation();
        },true);
        div3.addEventListener(&#39;click&#39;,function(e){
            console.log(&#39;div3&#39;);
        },true);
    </script>

当我们点击div2会依次弹出’div1’与’div2’,这也是因为在div2事件中我们设置了e.stopPropagation(),阻塞了目标元素的事件继续向下捕获。

event.target == event.currentTarget:

div.addEventListener('click',function(e){
	if(event.target == event.currentTarget){
        //需要执行的代码
    }
});

此方法不过多解释用的不多,如果你理解了上面的内容,这个方法也能理解。

五、补充:为什么要使用addEventListener()

从上面代码不难看出addEventListener()有如下的优点(以下是MDN的原话):

addEventListener() 是 W3C DOM 规范中提供的注册事件监听器的方法。它的优点包括:

  • 它允许给一个事件注册多个监听器。 特别是在使用AJAX库,JavaScript模块,或其他需要第三方库/插件的代码。
  • 它提供了一种更精细的手段控制 listener 的触发阶段。(即可以选择捕获或者冒泡)。
  • 它对任何 DOM 元素都是有效的,而不仅仅只对 HTML 元素有效。

六、取消默认事件

event.preventDefault()

默认事件指的是<a href=""></a><input type="submit"> 标签这类有默认行为的标签,通过点击可以跳转或提交。我们给这类标签绑定一个点击事件,设置事件对象的preventDefault()方法就可以阻止默认事件的发生。

   <a>点击跳转</a>
    <script>
        let a = document.querySelector(&#39;a&#39;);
        addEventListener(&#39;click&#39;,function(e){
            e.preventDefault();
        })
    </script>

那么我们如何才能知道一个标签是否有默认事件,打印事件对象的cancelable属性,通过事件执行就可以知道e.cancelable的结果,如果为false表示有默认事件,true则没有。

return false;

事件执行函数中设置return false取消默认事件,但此方法不常用。

【相关推荐:javascript学习教程

以上がJavaScript でのイベントのバブリングとキャプチャの詳細については、こちらをご覧ください。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。