incuisting/blogs

JavaScript事件---事件代理

Opened this issue · 0 comments

如下 html 片段

<ul>
    <li>11111111111</li>
    <li>22222222222</li>
    <li>33333333333</li>
</ul>

要对 li 添加 click 事件。通常做法:

var list = document.getElementsByTagName('li');
for (var i = 0; i < list.length; i++) {
    list[i].addEventListener('click', function(e) {
        console.log(e.target.textContent);
    })
}

这里还是只有3个元素添加事件,浏览器的性能不会受到什么影响。如果这里有1000个,都需要添加相同的事件,用循环的方法一个个添加明显不行,性能差不说,拓展性也不好。
那么,就要用到下面这种事件代理的写法了。

var ul = document.getElementsByTagName('ul')[0];
ul.addEventListener('click', function(e) {
    if (e.target.tagName === 'LI') {
        console.log(e.target.textContent);
    }
})

为ul添加一个时间的监听,利用事件冒泡,当li被点击的时候,点击事件会向上冒泡,当冒泡到ul时li的点击事件被监听到。然后通过判断target来确定被点击的是什么元素。
但是addEventListener并不支持IE 6 7 8,如果要在老浏览器上兼容,那么就要用attachEvent()

var ul = document.getElementsByTagName('ul')[0];
ul.attachEvent('onclick',function(e){
        var e = e||window.event;
          //IE没有e.target,有e.srcElement
          var target = e.target||e.srcElement;
     if(target.tagName.toLowerCase()=="li"){
             console.log(target.textContent);
 }
})

如何实现跨浏览兼容

function addEvent(element, eType, handle, bol) {
 if(element.addEventListener){           //如果支持addEventListener
     element.addEventListener(eType, handle, bol);
 }else if(element.attachEvent){          //如果支持attachEvent
     element.attachEvent("on"+eType, handle);
 }else{                                  //否则使用兼容的onclick绑定
     element["on"+eType] = handle;
 }
}

如果要做事件代理,对target 的判断就很必要

function judgmentTarget(e){
    var e = e||window.event;
    //IE没有e.target,有e.srcElement
    var target = e.target||e.srcElement;
  return target;
}

结合一下可以这样

function eventAgent(element,type,tag,handler){
   addEvent(element,type,function(event){
     event = event || window.event;
     var target = event || event.srcElement;
    if (target && target.tagName === tag.toUpperCase()) {
        handler;
    }
   });
  }