首頁  >  文章  >  web前端  >  前端中如何阻止事件傳播

前端中如何阻止事件傳播

php中世界最好的语言
php中世界最好的语言原創
2018-05-24 11:01:421782瀏覽

這次帶給大家前端如何阻止事件傳播,前端中阻止事件傳播的注意事項有哪些,以下就是實戰案例,一起來看一下。

做一個小demo,點擊按鈕出現浮層,點擊其它地方關閉浮層,寫一個簡單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';
});

但是實際上這樣寫了之後,按鈕都失效了,怎麼點都沒有反應。這是為什麼呢?
理解上一篇講的捕捉和冒泡事件後就很好理解這點了,可以[]()。
我們沒有指定監聽是在捕獲還是冒泡階段,瀏覽器預設是冒泡階段,當我們點擊按鈕時,捕獲階段沒有發生什麼時候,但是冒泡階段就不一樣了,首先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()函數。

相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!

推薦閱讀:

React-router v4使用步驟詳解

Chart.js輕量級圖表庫使用案例解析

Chart.js 輕量級HTML5圖表繪製工具庫使用步驟詳解

以上是前端中如何阻止事件傳播的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn