JavaScript事件代理(事件委托),即把原本需要绑定的事件委托给父元素,让父元素担当事件监听的职务。
众所周知,DOM操作是十分消耗性能的。所以重复的事件绑定简直是性能杀手。而事件代理的核心思想,就是通过尽量少的绑定,去监听尽量多的事件。
事件代理的核心思想:事件冒泡
.on( events [, selector ] [, data ], handler )
.delegate( selector, eventType, handler )
从jQuery 1.7开始,on()函数提供了绑定事件处理程序所需的所有功能,用于统一取代以前的bind()、 delegate()、 live()等事件函数。
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件代理</title>
<script type="text/javascript" src="http://tztest5.ptmind.cn/js/jquery-1.8.0.min.js?v=5/26"></script>
</head>
<body>
<ul class="list">
<li class="list_items">000</li>
<li class="list_items"><a href="javascript:void(0);">111</a></li>
<li class="list_items"><i>222</i></li>
<li>333</li>
</ul>
</body>
<script type="text/javascript">
/*
* <方式一>
* 每一个“.list_items”元素都被绑定了click事件,绑定的对象是“li.list_items”
* 这样的做法,当遇到数量超长的列表(ul)和表格(table)时性能开销非常大。
*/
$('.list_items').on('click', function (e) {
console.log(e.target.tagName); //"LI" or "A" or "I"
console.log(this); //LI
console.log($(this).text());
console.log(this.tagName);//LI
});
// 原生JavaScript代码<等价于方式一>:
[].forEach.call(document.querySelectorAll('.list_items'), function (elem) {
elem.addEventListener('click', function (e) {
console.log(e.target.tagName);
console.log(this.tagName);
}, false);
});
/*
* <方式二>
* 只有“.list”被绑定了click事件,绑定对象指向“ul.list”
* 开销大幅减少
*/
$('.list').on('click', '.list_items', function (e) {
console.log(e.target.tagName); //"LI" or "A" or "I"
console.log(this); //LI
console.log($(this).text());
console.log(this.tagName);//LI
});
//原生JavaScript代码<等价于方式二>:
var listElem = document.querySelector('.list');
listElem.addEventListener('click', function (e) {
var delegateTarget = this;
var fireTarget = e.target;
var eventTarget;
if (fireTarget.className !== 'list_items') {
function findParent(elem) {
if (elem === delegateTarget) {
return null;
}
var parent = elem.parentNode;
if (parent.className === 'list') {
return null;
}
if (parent.className === 'list_items') {
return parent;
}
findParent(parent);
}
eventTarget = findParent(fireTarget);
} else {
eventTarget = fireTarget;
}
if (!eventTarget) return false;
console.log('fireTarget: ' + fireTarget.tagName);
console.log('eventTarget: ' + eventTarget.tagName);
}, false);
/*
* <方式三>
* 带数据多事件
*/
var data = {name : 'ligang'};
$('.list').on('mouseenter mouseleave', ".list_items", data, function (e) {
var options = e.data;
if(e.type === "mouseenter"){
$(this).html("你好," + options.name);
}else if(e.type === "mouseleave"){
$(this).html("再见," + options.name);
}
});
</script>
</html>