事件元素javascript 事件委托


每日一贴,今天的内容关键字为事件元素

    可以利用事件委托直接给父元素绑定事件监听,用来检测其子元素内产生的事件,减少应用中时间监听的数量:

<ul id="test">
    <li>xxxxxxxxx</li>
    <li>yyyyyyyyy</li>
    <li>zzzzzzzzz</li>
    <li>qqqqqqqq</li>
</ul>
//没有应用事件委托
var li = document.getElementByTagName("li");
for(var i=0,len=ul.length;i<len;i++){
    li[i].addEventListener('click',function(){
        alert(this.innerHTML);
    },false);
}

//应用事件委托
var ul = document.getElementById("test");
ul.addEventListener('click',function(e){
  if(e.target == 'li'){
       alert(e.target.innerHTML);
    }
});
事件委托的另一个利益就是,所有为元素动态添加的子元素都拥有事件监听,比如上面的列表还会通过ajax继承插入下一页内容,那么后续插入的li也会有事件。明显当这个列表条目多时,事件委托的利益越明显--极大减少的元素上绑定的事件。

    但是现实运用中,列表内的元素可能更为复杂

<ul id="test">
    <li>xxxxxxxxx</li>
    <li>
         <p>wwwww</p>
         <p>ooooo</p>
    </li>
</ul>
这个时候点击li,e.target 可能是你点击到的 p 
    每日一道理
航行者把树比作指引方向的路灯,劳动者把树比作遮风挡雨的雨伞,诗人把树比作笔下的精灵,而我却要把树比作教师,它就是为我们遮风挡雨的伞,指明方向的路灯,打开知识殿堂的金钥匙。
var ul = document.getElementById("test");
ul.addEventListener('click',function(e){
      //e.target可能是p,这时须要向上查找
  if(e.target == 'li' || e.target.parentNode=='li'){
         //do something
    }
});
现实中的DOM结构比这复杂多了,咋办?一直的向上查找,晓得匹配到对应的元素或者到父元素还没匹配到时终止。
var ul = document.getElementById('test');
ul.addEventListener('click',function(e) {
    var el = e.target;
    while (el) {
        if (el.tagName === 'li') {
            alert(el.innerHTML);
            break;
        } else {
            //向上查找
            el = el.parentNode;
            //到ul还没找到就终止  
            if (el === this) break;  
        }
    }
}, false);
可见事件委托也不能滥用,不然反复的查找是低效的。

    jquery中 on 方法也供给了事件委托,看下jquery的实现方法

//cur 对应上文中 li,  this 对应ul
//就看这条for语句就行了,里头if是对其它事件的处理
for (; cur != this; cur = cur.parentNode || this) {
    // Don't check non-elements (#13208)
    // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
    if (cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click")) {
        matches = [];
        for (i = 0; i < delegateCount; i++) {
            handleObj = handlers[i];

            // Don't conflict with Object.prototype properties (#13203)
            sel = handleObj.selector + " ";

            if (matches[sel] === undefined) {
                matches[sel] = handleObj.needsContext ? jQuery(sel, this)
                    .index(cur) >= 0 : jQuery.find(sel, this, null, [cur])
                    .length;
            }
            if (matches[sel]) {
                matches.push(handleObj);
            }
        }
        if (matches.length) {
            handlerQueue.push({
                elem: cur,
                handlers: matches
            });
        }
    }
}
 

文章结束给大家分享下程序员的一些笑话语录: 那是习惯决定的,一直保持一个习惯是不好的!IE6的用户不习惯多标签,但是最终肯定还是得转到多标签的浏览器。历史(软件UI)的进步(改善)不是以个人意志(习惯)为转移的!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值