每日一贴,今天的内容关键字为事件元素
可以利用事件委托直接给父元素绑定事件监听,用来检测其子元素内产生的事件,减少应用中时间监听的数量:
<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); } });
但是现实运用中,列表内的元素可能更为复杂
<ul id="test"> <li>xxxxxxxxx</li> <li> <p>wwwww</p> <p>ooooo</p> </li> </ul>
var ul = document.getElementById("test"); ul.addEventListener('click',function(e){ //e.target可能是p,这时须要向上查找 if(e.target == 'li' || e.target.parentNode=='li'){ //do something } });
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)的进步(改善)不是以个人意志(习惯)为转移的!