事件模型和事件委託

如夢灬初醒發表於2020-10-06

事件模型

模型型別:DOM 0(原始事件型別)、DOM 2

DOM 0
  • 直接在dom上繫結事件。列如:div.nclick =function(){};
    特點:
  • 1、DOM0級事件模型是早期的事件模型,所有的瀏覽器都是支援的。
  • 2、一個DOM物件只能註冊一個同型別的函式,因為註冊多個同型別的函式的話,就會發生覆蓋,之前註冊的函式就會無效。
  • 3、DOM0不會阻止事件冒泡的發生
DOM 2

使用addEventListener和removeEventListener來註冊和解除事件
支援事件流的捕獲和冒泡,通過addEventListener(‘事件名稱’,‘事件回撥’,‘捕獲/冒泡’)第三個引數的設定(預設false即冒泡),制定事件觸發是在捕獲過程還是冒泡過程。
addEventListener() 移除事件必須使用外部函式
在DOM 2中 一個dom物件可以註冊多個相同型別的事件,不會發生事件的覆蓋,會依次的執行各個事件函式。

"DOM 2"規定事件流的三個階段:

  • 第一階段:捕獲階段,從全域性物件傳導到目標節點
  • 第二階段:目標階段,事件在目標節點上觸發
  • 第三階段:冒泡階段,從目標節點傳回window物件

事件捕獲階段、事件目標階段和事件冒泡階段。首先發生的是事件捕獲,為截獲事件提供了機會;然後是實際的目標接收到事件;最後一個階段是冒泡階段,可以在這個階段對事件作出響應,
即:事件捕獲->事件處理->事件冒泡

事件委託

事件委託原理:事件委託是利用事件的冒泡原理來實現的,何為事件冒泡呢?
冒泡事件就是document到觸發事件的那個節點一層層向下捕獲直至事件源然後一層層向上冒泡。這就是事件冒泡,利用這個冒泡機制減少DOM操作,有一點要注意就是onclick不支援捕獲事件,
舉個例子:頁面上有這麼一個節點樹,div>ul>li>a;比如給最裡面的a加一個click點選事件,那麼這個事件就會一層一層的往外執行,執行順序a>li>ul>div,有這樣一個機制,那麼我們給最外面的div加點選事件,那麼裡面的ul,li,a做點選事件的時候,都會冒泡到最外層的div上,所以都會觸發,這就是事件委託,委託它們父級代為執行事件。
事件委託就是利用冒泡的原理,把本應該新增到某個元素上的事件委託給他的父級,從而減少DOM互動達到網頁優化。

<ul id="ul">
    <li><a href="#>aa</a></li>
    <li><a href="#>bb</a></li>
    <li><a href="#>nn</a></li>
 </ul>
 <script>
      var ul = document.getElementById("ul");
      ul.onclick = function(e){
        var e = e || window.event;
        var target = e.target || e.srcElement;
        if(target.tagName == 'LI'){
         console.log(target.innerHTML);
        }
      }
</scropt>

Event物件提供了一個屬性叫target,可以返回事件的目標節點,也就是事件源節點,target就可以表示為當前的事件操作的dom,這個是有相容性的,標準瀏覽器用ev.target,IE瀏覽器用event.srcElement,
此時只是獲取了當前節點的位置,並不知道是什麼節點名稱,也可以用nodeName來獲取具體是什麼標籤名

事件委託優點:

  1. 只在記憶體中開闢了一塊空間,節省資源同時減少了dom操作,提高效能
  2. 對於新新增的元素也會有之前的事件

總結:什麼樣的事件可以用事件委託,什麼樣的事件不可以用呢?
適合用事件委託的事件:click,mousedown,mouseup,keydown,keyup,keypress。
不適合的就有很多了,舉個例子,mousemove,mouseout,每次都要計算它的位置,非常不好把控,在不如說focus,blur之類的,本身就沒用冒泡的特性,自然就不能用事件委託了。

相關文章