委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。点击事件这么频繁,主要是想办法解决浏览器的点击该怎么安排,设计比较好
事件委托
解决的问题:有很多的dom需要添加事件处理
“事件委托” 的本质是利用了事件冒泡的特性。把事件处理函数绑定到容器元素上,当容器内的元素触发事件时,就会冒泡到容器上。此时可以判断事件的源头是谁,再执行对应的事件处理函数。
- 先用实例理解冒泡
html
<div id="parent">
父元素
<div id="child">
子元素
</div>
</div>
js
var parent = document.getElementById("parent");
var child = document.getElementById("child");
document.body.addEventListener("click", function(e) {
console.log("冒泡-body");
}, false);
parent.addEventListener("click", function(e) {
console.log("冒泡-parent");
}, false);
child.addEventListener("click", function(e) {
console.log("冒泡-child");
}, false);
红色为parent,蓝色为child
点击蓝色
点击红色
可以看到事件触发顺序是由内到外的(想象下dom树结构),这就是事件冒泡,虽然只点击子元素,但是它的父元素也会触发相应的事件,至于怎么阻止,就不细说了
- 经典的例子,为每个li绑定事件
<ul id="btn">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
事件委托实现(提醒:使用 .onclick 这样的事件属性来绑定事件有一个非常大的缺点,重复赋值会覆盖旧值。)
var btn = document.getElementById('btn');
btn.addEventListener('click', btnClick);
function btnClick(e) {
var that = this;
if (e.target.nodeName.toLowerCase() === 'li') {
//do something
}
}
- 其中JQuery中的$.on()就很好地实现了事件委托
$('body').on('click','li',function(){
// do something
})
只要明白冒泡原理,应该是很好理解的
点击事件解决方案
- 最近看到css魔法的一个解决方案action,很赞
- 具体思路
- 利用html5的data-*属性设置统一的事件标识
- 事件以
var list= {a:function(){ }}
方式存储 - 再用JQuery的$.on()实现事件委托
$.data()
获取对应的data-*
,list[$.data()]
设置响应事件- 实现代码
HTML
<button data-action="lucky-draw">Lucky Draw</button>
<button data-action="some-action">Button</button>
<a href="#" data-action="another-action">Link</a>
JS
$(function() {
var actionList = {
'lucky-draw': function() {
console.log("I am lucky-draw");
},
'some-action': function() {
console.log("I am some-action");
},
// ...
'another-action': function() {
console.log("I am another-action");
}
};
$('body').on('click', '[data-action]', function() {
var actionName = $(this).data('action');
var action = actionList[actionName];
if ($.isFunction(action)) action();
});
// 添加新的点击事件
// HTML
$('body').append('<a href="#" data-action="more-action">Link</a>')
// JS
$.extend(actionList, {
'more-action': function() {
console.log('I am more');
}
})
})