Understanding of Event Delegation

  event delegationhtml

  参考连接:https://learn.jquery.com/events/event-delegationhttps://davidwalsh.name/event-delegatenode

  当咱们须要为一些节点绑定事件时,咱们一般会这么作jquery

<ul id ="test">
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
</ul>

<script>
   $("#test li").on("click", function(event) {
event.proventDefalut(); console.log($(
this).text()); }) </script>

  因而,咱们触发点击事件后,就会弹出对应的text值;dom

  可是,后来咱们发现须要添加新的li标签了函数

$("test").apend("<li>5</li>")

  虽然咱们在理想中认为新添加的元素也应该在被点击后可以输出它的text,然而现实很骨感,点击它并不会有什么事情发生,由于新添加元素并无绑定到event handler;this

  如今咱们须要理解一个概念,Event Propagation。spa

  在咱们点击了某个li标签,它的click事件会被触发,而后向上冒泡,直达dom tree的根节点(document root);本例中的示意图大体是这样的代理

  licode

  ulhtm

  body

  html

  document root

  这就意味着我每次点击一个小小的li标签,就至关于点击了整个文档。——这就是eventPropagation 或者称为 eventbubbling的概念;

  在咱们了解event bubble是如何做用以后,咱们就能够实现一个代理事件delegated event

// Attach a delegated event handler
$( "#test" ).on( "click", "a", function( event ) {
    event.preventDefault();
    console.log( $( this ).text() );
});

  咱们如今在.on()函数的第二个参数添加了一个“a”,它是做为ul标签的子元素存在的。当咱们点击到ul下的任意一个a标签(不管它是在点击事件绑定前就存在的仍是后来建立的),它会触发event bubble,当事件冒泡到ul上时(即触发ul的点击事件),会执行咱们为ul绑定的回调函数,而后阻止点击事件继续冒泡(避免影响到其余元素)。

  至此,咱们能够发现,咱们不须要再为某个父元素下的每一个子元素都绑定诸如click事件,而是去为该父元素绑定事件。这个就是事件代理,借助冒泡机制将子元素的事件放在父元素上托管。

  JQuery中咱们经过.on()的第二个参数来实现event delegation,如今咱们看看原生JS的实现方式,区别主要体如今如何匹配到指定的子元素上。

document.getElementById("test").addEventListener("click", function(e) {
    // e.target is the clicked element!
    // If it was a list item
    if(e.target && e.target.nodeName == "LI") {
        // List item found!  Output the ID!
        console.log("List item",e.target," was clicked!");
    }
});
//实现ul下li点击事件的代理。

  一个div#test下有多个子节点,咱们须要为a.classA的子元素绑定点击事件,实现方式以下:

// Get the parent DIV, add click listener...
document.getElementById("test").addEventListener("click",function(e) {
    // e.target was the clicked element
  if (e.target && e.target.matches("a.classA")) {
    console.log("Anchor element clicked!");
    }
});

  在上方实现匹配到咱们所关心的带有classA的class名的元素还可使用正则匹配的方式:

var re = new RegExp('\\b'+class+'\\b');
re.test(e.target.className);

  re.test(e.target.className)会返回一个bool类型的变量,当匹配到咱们关心的元素,返回true,不然返回false;

相关文章
相关标签/搜索