ホームページ  >  記事  >  ウェブフロントエンド  >  フロントエンドでのイベントの伝播を防ぐ方法

フロントエンドでのイベントの伝播を防ぐ方法

php中世界最好的语言
php中世界最好的语言オリジナル
2018-05-24 11:01:421782ブラウズ

今回はフロントエンドでのイベントの蔓延を防ぐ方法を紹介します。フロントエンドでのイベントの蔓延を防ぐための注意点は何ですか?実際の事例を見てみましょう。

小さなデモを作成し、ボタンをクリックしてフローティング レイヤーを表示し、他の場所をクリックしてフローティング レイヤーを閉じ、簡単な CSS を作成します

<style>
.wrapper{
    position:relative;
    display:inline-block;
}
.popover{
    position:absolute;
    border:1px solid red;
    left:100%;
    top:0;
    padding:10px;
    margin-left:10px;
    background:white;
    display: none;  /*默认隐藏*/
}
.popover::before{
    position:absolute;
    content:'';
    top:5px;
    right:100%;
    border:10px solid transparent;
    border-right-color:red;
}
.popover::after{
    position:absolute;
    content:'';
    top:5px;
    right:100%;
    border:10px solid transparent;
    border-right-color:white;
    margin-right:-1px;
}

</style>
<p id="wrapper" class=&#39;wrapper&#39;>
    <button id="clickMe">点我</button>
    <p id="popover" class="popover">
        <input type="checkbox">浮层
    </p>
</p>
<script>
    clickMe.addEventListener('click',function(){
        popover.style.display = 'block';
    });
</script>

さて、ページ上の空白部分をクリックして閉じたらどうなるでしょうか?どのような方法を使用すればよいでしょうか? 以下のようなコード

document.addEventListener('click',function(){
    popover.stely.display = 'none';
});

のような監視ドキュメントが思いつきやすいのですが、実際にこうして書いてみるとボタンが無効となり、どれをクリックしても反応しません。どうしてこれなの?
前回の記事で述べた攻略とバブリングイベントを理解すると、簡単に理解できるようになります。
モニタリングがキャプチャ フェーズであるかバブリング フェーズであるかは指定しませんでした。ボタンをクリックすると、キャプチャ フェーズは発生しません。まず、ボタンは異なります。 code> の関数が最初にトリガーされ、次に <code>document の関数もトリガーされ、フローティング レイヤーが再び非表示になっているように見えます。 button上函数先触发,然后document上函数也触发了,导致准备出现的浮层又被隐藏了。
那你可能要问,button上的事件执行了没?其实这两个事件都执行了,只是时间太短,浏览器默认一起执行了,可以在里面加一个debugger,就可以看到了。

clickMe.addEventListener('click',function(){
    popover.style.display = 'block';
});

那该怎么解决呢?最简单的方法是,除了要执行popover.style.display = 'block',还要阻止事件传播

clickMe.addEventlistener('click',function(){
    popover.style.display = 'block';
});

popover.addEventListener('click',function(e){
    e.stopPropagation();
});

这里为什么添加在按钮的父元素上面呢?如果不添加在父元素上面,点击浮层的时候,浮层也会被关闭。

如果页面上有很多监听器的话,这个方法是比较浪费内存的,比较省内存的方法用JQuery 做

$(clickMe).on('click',function(){
    $(popover).show();
    $(document).one('click',function(){
        $(popover).hide();
    });
});
$(wrapper).on('click',function(e){
    e.stopPropagation();    
})

一开始不监听,只在popover`show`的时候监听一次,马上关掉,这叫做清理战场。
$(wrapper).on('click',false) 和下面的代码完全等价

$(wrapper).on('click',function(e){
    e.preventDefault();     //阻止默认事件
    e.stopPropagation();    //阻止传播
})

但是如果页面中有checkbox,你在它的父元素任何一层,包括checkbox自己,添加了组织默认事件那么这个checkbox就没办法被check

这里有个问题,如果没有阻止事件传播,向下面这样,会发生什么事情呢?

$(clickMe).on('click',function(){
    $(popover).show();
    $(document).one('click',funtion(){
        $(popover).hide();
    });
});

当然了,和之前一样,什么事情也不会发生,那当我点击按钮之后里面都发生了那些事情呢?
当我点击了按钮之后,它会做两件事情,首先把popover`show出来,然后把hide函数添加到document上面,当事件传播到document`,就会又把它给隐藏了。

可以给它添加一个setTimeout()函数来解决这个问题

$(clickMe).on('click',function(){
    $(popover).show();
    setTimeout(function(){
        $(document).one('click',function(){
            $(popover).hide();
        })
    },0)
});

setTimeout(fn,0)这个0不是马上执行,而是尽快执行,具体是在冒泡结束在执行这里的函数,也就是说,当冒泡结束后,在把监听事件添加到document上面,等待用户下次点击在执行。

总结:

  1. 同时监听buttondocument,点啥都没反应,因为两个函数都执行了,用阻止事件传播解决了,比较浪费内存

  2. 好一定的方法是用jQuery 做,点击button后在监听document,关闭了就不再监听,不阻止事件传播,点啥也没反应,两种解决方法:一种是阻止事件传播,另一种是添加一个setTimeout()それでは、button のイベントが実行されたかどうかを尋ねる場合があります。実際、両方のイベントが実行されますが、時間が短すぎます。ブラウザはデフォルトでそれらを一緒に実行します。内部に debugger を追加すると、それを確認できます。

    rrreee
  3. それではどうやって解決すればいいのでしょうか?最も簡単な方法は、popover.style.display = 'block' の実行に加えて、イベントの伝播も防ぐことです
rrreee

ここでボタンの親要素にイベントが追加されるのはなぜですか?親要素に追加されていない場合は、クリックするとフローティングレイヤーが閉じられます。

ページ上に多くのリスナーがある場合、この方法はメモリをより無駄に消費します。よりメモリを節約する方法は、JQuery を使用することです

rrreee

最初はリッスンせず、popover`show のときのみです。 ` 一度監視してすぐに停止することを、戦場のクリーンアップと呼びます。 $(wrapper).on('click',false) は次のコード rrreee
と完全に同等ですが、ページに checkbox がある場合は、 checkbox 自体を含む要素のいずれかのレイヤーが組織のデフォルト イベントを追加する場合、この checkboxcheck にすることはできません。

ここで質問がありますが、イベントの蔓延を防げなかった場合、次のようになりますか? rrreee もちろん、以前と同様に何も起こりません。ボタンをクリックすると何が起こったでしょうか?
ボタンをクリックすると、2 つの処理が実行されます。まず、popover`show が表示され、次に hide 関数が に追加されます。 >document 上記では、イベントが document` に伝播すると、再び非表示になります。

この問題を解決するには、setTimeout() 関数を追加できますrrreeesetTimeout(fn,0)この 0 はそうではありませんすぐに実行されますが、できるだけ早く実行します。具体的には、この関数はバブリングが終了した後に実行されます。つまり、バブリングが終了したら、listen イベントを document に追加して待機します。ユーザーが次回実装するときにクリックします。

概要:

  1. buttondocument を同時に監視します。クリックしても何も起こりません両方の関数が実行され、メモリの無駄であるイベントの伝播を防ぐことで問題が解決されます🎜🎜
  2. 🎜 最良の方法は、jQuery を使用し、button をクリックして、 document をリッスンします。オフにするとリッスンしなくなります。イベントの伝播は妨げられず、クリックしても何も起こりません。解決策は 2 つあります。1 つは次の方法です。イベントの伝播を防ぐこと、もう 1 つは setTimeout() 関数を追加することです。 🎜🎜🎜🎜この記事の事例を読んだ後は、この方法を習得したと思います。さらに興味深い情報については、php 中国語 Web サイトの他の関連記事に注目してください。 🎜🎜推奨読書: 🎜🎜🎜 React-router v4 を使用する手順の詳細な説明🎜🎜🎜🎜🎜Chart.js 軽量チャート ライブラリのユースケース分析🎜🎜🎜🎜🎜Chart.js 軽量の使用手順の詳細な説明HTML5 チャート描画ツール ライブラリ 🎜🎜🎜🎜🎜

以上がフロントエンドでのイベントの伝播を防ぐ方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。