JS 中的事件綁定、事件監聽、事件委托

liftweb 9年前發布 | 12K 次閱讀 JavaScript開發 JavaScript

事件綁定

  • 要想讓 JavaScript 對用戶的操作作出響應,首先要對 DOM 元素綁定事件處理函數。所謂事件處理函數,就是處理用戶操作的函數,不同的操作對應不同的名稱
  • 在 JavaScript 中,有三種常用的綁定事件的方法

    • 在 DOM 元素中直接綁定;
    • 在 JavaScript 代碼中綁定;
    • 綁定事件監聽函數
    </li> </ul>

    在 DOM 中直接綁定事件

    <input type="button" value="click me" onclick="hello()">

    <script> function hello(){ alert("hello world!"); } </script> </code></pre>

    在 JavaScript 代碼中綁定事件

    • 在 JavaScript 代碼中(即script標簽內)綁定事件可以使 JavaScript 代碼與 HTML 標簽分離,文檔結構清晰,便于管理和開發
    <input type="button" value="click me" id="btn">

    <script> document.getElementById("btn").onclick = function(){ alert("hello world!"); } </script> </code></pre>

    使用事件監聽綁定事件

    • 關于事件監聽,W3C規范中定義了3個事件階段,依次是捕獲階段、目標階段、冒泡階段
    • 起初 Netscape 制定了 JavaScript 的一套事件驅動機制(即事件捕獲)。隨即 IE 也推出了自己的一套事件驅動機制(即事件冒泡)。最后 W3C 規范了兩種事件機制,分為捕獲階段、目標階段、冒泡階段。IE8以前IE一直堅持自己的事件機制(前端人員一直頭痛的兼容性問題), IE9 以后 IE 也支持了W3C規范

    W3C規范

    • 語法
    element.addEventListener(event, function, useCapture)
    
    • event : (必需)事件名,支持所有 DOM 事件。
    • function :(必需)指定要事件觸發時執行的函數。
    • useCapture :(可選)指定事件是否在捕獲或冒泡階段執行。 true ,捕獲。 false ,冒泡。默認 false

    • 注: IE8 以下不支持

    <input type="button" value="click me" id="btn1">

    <script> document.getElementById("btn1").addEventListener("click",hello); function hello(){ alert("hello world!"); } </script> </code></pre>

    IE標準

    • 語法:
    element.attachEvent(event, function)
    
    • event :(必需)事件類型。需加“on“,例如: onclick 。
    • function :(必需)指定要事件觸發時執行的函數
    <input type="button" value="click me" id="btn2">

    <script> document.getElementById("btn2").attachEvent("onclick",hello); function hello(){ alert("hello world!"); } </script> </code></pre>

    事件監聽的優點

    • 可以綁定多個事件
    <input type="button" value="click me" id="btn3">

    <script> var btn3 = document.getElementById("btn3"); btn3.onclick = function(){ alert("hello 1"); //不執行 } btn3.onclick = function(){ alert("hello 2"); //執行 } </script> </code></pre>

    常規的事件綁定只執行最后綁定的事件

    <input type="button" value="click me" id="btn4">

    <script> var btn4 = document.getElementById("btn4"); btn4.addEventListener("click",hello1); btn4.addEventListener("click",hello2);

    function hello1(){ alert("hello 1"); } function hello2(){ alert("hello 2"); } </script> </code></pre>

    兩個事件都執行了

    • 可以解除相應的綁定
    <input type="button" value="click me" id="btn5">

    <script> var btn5 = document.getElementById("btn5"); btn5.addEventListener("click",hello1);//執行了 btn5.addEventListener("click",hello2);//不執行 btn5.removeEventListener("click",hello2);

    function hello1(){ alert("hello 1"); } function hello2(){ alert("hello 2"); } </script> </code></pre>

    • 封裝事件監聽
    <input type="button" value="click me" id="btn5">

    //綁定監聽事件 function addEventHandler(target,type,fn){ if(target.addEventListener){ target.addEventListener(type,fn); }else{ target.attachEvent("on"+type,fn); } }

    //移除監聽事件 function removeEventHandler(target,type,fn){ if(target.removeEventListener){ target.removeEventListener(type,fn); }else{ target.detachEvent("on"+type,fn); } }

    //測試 var btn5 = document.getElementById("btn5"); addEventHandler(btn5,"click",hello1);//添加事件hello1 addEventHandler(btn5,"click",hello2);//添加事件hello2 removeEventHandler(btn5,"click",hello1);//移除事件hello1 </code></pre>

    事件委托

    • 事件委托就是利用冒泡的原理,把事件加到父元素或祖先元素上,觸發執行效果
    <input type="button" value="click me" id="btn6">

    var btn6 = document.getElementById("btn6"); document.onclick = function(event){ event = event || window.event; var target = event.target || event.srcElement; if(target == btn6){ alert(btn5.value); } } </code></pre>

    事件委托優點

    • 提高JavaScript性能。事件委托可以顯著的提高事件的處理速度,減少內存的占用
    • 傳統寫法
    <ul id="list">
      <li id="item1" >item1</li>
      <li id="item2" >item2</li>
      <li id="item3" >item3</li>
    </ul>

    <script> var item1 = document.getElementById("item1"); var item2 = document.getElementById("item2"); var item3 = document.getElementById("item3");

    item1.onclick = function(){ alert("hello item1"); } item2.onclick = function(){ alert("hello item2"); } item3.onclick = function(){ alert("hello item3"); } </script> </code></pre>

    • 事件委托
    <ul id="list">
      <li id="item1" >item1</li>
      <li id="item2" >item2</li>
      <li id="item3" >item3</li>
    </ul>

    <script> var item1 = document.getElementById("item1"); var item2 = document.getElementById("item2"); var item3 = document.getElementById("item3");

    document.addEventListener("click",function(event){ var target = event.target; if(target == item1){ alert("hello item1"); }else if(target == item2){ alert("hello item2"); }else if(target == item3){ alert("hello item3"); } }) </script> </code></pre>

    • 動態的添加DOM元素,不需要因為元素的改動而修改事件綁定
    • 傳統寫法
    <ul id="list">
      <li id="item1" >item1</li>
      <li id="item2" >item2</li>
      <li id="item3" >item3</li>
    </ul>

    <script> var list = document.getElementById("list");

    var item = list.getElementsByTagName("li"); for(var i=0;i<item.length;i++){ (function(i){ item[i].onclick = function(){ alert(item[i].innerHTML); } })(i) }

    var node=document.createElement("li"); var textnode=document.createTextNode("item4"); node.appendChild(textnode); list.appendChild(node);

    </script> </code></pre>

    • 點擊item1到item3都有事件響應,但是點擊item4時,沒有事件響應。說明傳統的事件綁定無法對動態添加的元素而動態的添加事件。
    • 事件委托
    <ul id="list">
      <li id="item1" >item1</li>
      <li id="item2" >item2</li>
      <li id="item3" >item3</li>
    </ul>

    <script> var list = document.getElementById("list");

    document.addEventListener("click",function(event){ var target = event.target; if(target.nodeName == "LI"){ alert(target.innerHTML); } })

    var node=document.createElement("li"); var textnode=document.createTextNode("item4"); node.appendChild(textnode); list.appendChild(node);

    </script> </code></pre>

    • 當點擊item4時,item4有事件響應。說明事件委托可以為新添加的DOM元素動態的添加事件

     

    來自:http://blog.poetries.top/2016/12/13/js-event-listener/

     

 本文由用戶 liftweb 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!