1. 程式人生 > >js事件冒泡、阻止事件冒泡以及阻止預設行為

js事件冒泡、阻止事件冒泡以及阻止預設行為

這裡是修真院前端小課堂,每篇分享文從

【背景介紹】【知識剖析】【常見問題】【解決方案】【編碼實戰】【擴充套件思考】【更多討論】【參考文獻】

八個方面深度解析前端知識/技能,本篇分享的是:

js事件冒泡、阻止事件冒泡以及阻止預設行為

大家好,我是IT修真院武漢分院web第17期的學員吳三水,一枚正直純潔善良的web程式設計師。

今天給大家分享一下,修真院官網js(職業)任務四,深度思考中的知識點——js事件冒泡、阻止事件冒泡以及阻止預設行為

 

1.背景介紹

事件冒泡

故名思意,事件冒泡就像水底氣泡浮到水面這一過程。即是事件從最底層逐個經過上面一級級事件的過程,就是事件冒泡。

 

預設事件

預設事件就是瀏覽器自己的行為,比如我們在點選a標籤<a href="#">時候,瀏覽器跳轉到指定頁面。比如當我們滾動滑鼠時頁面會向下滾動。

 

2.知識剖析

事件冒泡 :當一個元素接收到事件的時候 會把他接收到的事件傳給自己的父級,一直到window 。

 

事件冒泡傳遞的僅僅只是事件,並不會傳遞其他東西,如果父級沒有繫結事件函式的話,就算傳遞了事件,也不會有什麼表現,但是我們要清楚,事件是確確實實傳遞到了)

 

我們看下面程式碼:

             //js

            var a = document.getElementById("123");

            var b = document.getElementById("321");

            a.addEventListener("click", function () {

                alert(1);

            })

            b.addEventListener("click", function () {

                alert(2);

            })

 

            //html

        <div id="123" style="display:inline-block;width:200px;height:200px;background: #ff0000;">我是父級元素

        <div id="321" style="display:inline-block;margin-left:200px;width:100px;height:100px;background:#000;color:#fff;">我是子級元素</div>

    </div>

 

上面兩個父子關係的div,然後分別加了點選事件,當我們在子div裡面點選的時候,會發現彈出了一次1,接著又彈出了2,這說明點選的時候,不僅子div的事件被觸發了,它的父級的點選事件也觸發了,說明子div的將事件傳遞給了父div。這種就是冒泡事件。

 

 

3.常見問題

大多數時候,事件冒泡給我們帶來的缺是困擾,比如下面這個:

 

 

             //js

            var b = document.getElementById("321");

            b.addEventListener("click", function () {

            a.style.display = "block";

            })

            document.onclick = function () {

            a.style.display = "none";

            }

 

            //html

          <div id="123" style="display:inline-block;width:200px;height:200px;background: #ff0000;">點選除了#321外的地方我會顯示</div>

       <div id="321" style="display:inline-block;margin-left:200px;width:100px;height:100px;background:#000;color:#fff;">點選我#123會隱藏</div>

 

這個時候我們測試發現,怎麼點選#321面板,#123面板都不會顯示了,為什麼呢?就是冒泡的原因,我們來分析下程式碼,當點選#321的時候,他會觸發父親級別的點選事件,然後一層一層的往上傳,所以document的點選事件自然也被觸發了,然後執行了自己身上的繫結事件,讓#123面板消失。所以當你點選#321的時候首先,讓粉絲面板顯示,只是事件執行太快了,很快又執行了document的點選事件,讓面板隱藏。 不信可以再兩個事件之間加一個彈出,就可以測試。

 

4.解決方案

解決辦法就是取消冒泡:

取消事件冒泡可以運用下面方法:

 

e.stopPropagation();

stopPropagation() 方法定義是:不再派發事件。所以直接呼叫的event 即可

 

window.event.cancelBubble = true;

這裡的cancelBubble是 IE事件物件的屬性定義:是否取消冒泡,設為true就可以了。

 

 

 

 5.編碼實戰

 

 

function stopBubble(e) {

    //如果提供了事件物件,則這是一個非IE瀏覽器

   if ( e && e.stopPropagation )

      //因此它支援W3C的stopPropagation()方法

      e.stopPropagation();

  else

  //否則,我們需要使用IE的方式來取消事件冒泡

    window.event.cancelBubble = true;

}

//js

            var b = document.getElementById("321");

            b.addEventListener("click", function (e) {// 紅色面板加事件

            a.style.display = "block";

             stopBubble(e);//這樣就不會再冒泡給父級了 

            })

            document.onclick = function () {

            a.style.display = "none";

            }

 

 

6.擴充套件思考

如何阻止事件的預設行為?
阻止事件的預設行為可以運用下面方法:

 

 

1.e.preventDefault();

 

2.window.event.returnValue =false;

 

注:preventDefault它是事件物件(Event)的一個方法,作用是取消一個目標元素的預設行為。既然是說預設行為,當然是元素必須有預設行為才能被取消,如果元素本身就沒有預設行為,呼叫當然就無效了。什麼元素有預設行為呢?如連結<a>,提交按鈕等。當Event 物件的 cancelable為false時,表示沒有預設行為,這時即使有預設行為,呼叫preventDefault也是不會起作用的。

 

  function stopDefault(e){

                         if(e && e.preventDefault){               //判斷瀏覽器是非IE瀏覽器

                                  e.preventDefault();            //非IE瀏覽器下使用preventDefault方法

                         }else{

                                  //IE瀏覽器下令事件(window.event)的returnValue屬性為false;

                                  window.event.returnValue = false;

                         }

                         return false;

                 }

                 //html

                 <a href="http://www.baidu.com" id="test">百度</a>

                 //js

                    window.onload = function(){

 

                 var test = document.getElementById('test');

 

                 test.onclick = function(e){                     //當單擊此超連結時執行這個函式

 

                         alert('URL:' + this.href + ',不會跳轉');

 

                         stopDefault(e);

 

                 }

 

        }

 

7.參考文獻 

JavaScript事件——冒泡、捕獲
js事件(Event)之(四)阻止預設操作

 

8.更多討論 

1.阻止事件冒泡和預設行為還有其他方法嗎?

  可以利用return false;來阻止 事件冒泡和靜默行為。 注意:javascript的return false只會阻止預設行為,而用jQuery的話則既阻止預設行為又防止物件冒泡。

可以利用return false;來阻止 事件冒泡和靜默行為。
注意:javascript的return false只會阻止預設行為,而用jQuery的話則既阻止預設行為又防止物件冒泡

//原生js,只會阻止預設行為,不會停止冒泡

var a = document.getElementById("testA");

a.onclick = function(){

    return false;//當然 也阻止了事件本身

};

 

 

//jQuery,既阻止預設行為又停止冒泡

$("#testA").on('click',function(){

    return false;//當然 也阻止了事件本身

});

 

2.既然return false 和 e.preventDefault()都是一樣的效果,那它們有區別嗎?當然有。

        僅僅是在HTML事件屬性 和 DOM0級事件處理方法中 才能通過返回 return false 的形式組織事件宿主的預設行為。

 

3.事件執行的原理?

 

      當一個事件發生後,這個事件就要開始傳播(從裡到外或者從外向裡)。為什麼要傳播呢?因為事件源本身(可能)並沒有處理事件的能力, 即處理事件的函式(方法)並未繫結在該事件源上。例如我們點選一個按鈕時,就會產生一個click事件,但這個按鈕本身可能不能處理這個事件,事件必須從這個按鈕傳播出去, 從而到達能夠處理這個事件的程式碼中(例如我們給按鈕的onclick屬性賦一個函式的名字, 就是讓這個函式去處理該按鈕的click事件),或者按鈕的父級繫結有事件函式,當該點選事件發生在按鈕上,按鈕本身並無處理事件函式,則傳播到父級去處理。

 

鳴謝

感謝大家觀看!

今天的分享就到這裡啦,歡迎大家點贊、轉發、留言、拍磚~

 

 

PPT連結 視訊連結

更多內容,可以加入IT交流群565734203與大家一起討論交流

這裡是技能樹·IT修真院:https://www.jnshu.com,初學者轉行到網際網路的聚集地