事件委托又名事件代理。
定义:事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
为了便于理解,我们还是用取快递的例子:
HW公司有三个员工有快递,那么有两个方式取快递。
(1)三个人都等在公司门口,等快递小哥过来取快递;
(2)委托前台帮忙代取快递,并核对信息;
即,对于(2)对于公司已有员工的快递,前台也能核对信息签收,对于公司新入职的员工,也能进行记录并核对。
在javascript中访问dom节点的次数越多,引起浏览器重绘与重排的次数就会越多,就会延长整个页面交互事件。如果使用事件委托,将所有与dom有关的操作放在js中,与dom的交互只有一次,就能提高性能。
对很多元素进行操作时,如果一个一个执行渲染,那真的是对性能的巨大浪费,但是转换思维,如果对他的父元素进行操作,那么只需进行一次,既节省内存,又提高了性能。
引用学习中的例子进行讲解:
- 111
- 222
- 333
- 444
功能:点击li元素,实现弹框“触发li弹窗事件”
常规写法:
var ulList = document.getElementById("ul_list");
var liList = ulList.getElementsByTagName("li");
for (var i = 0; i < liList.length; i++) {
liList[i].onclick = function () {
alert("触发li弹窗事件")
}
}
对于常规写法,首先要找到父级元素ul,在循环给子元素添加事件,如果是100个li元素,那性能自然是不高。
事件委托:
var ulList = document.getElementById("ul_list");
ulList.onclick = function () {
alert("触发li弹窗事件")
}
对于事件委托写法,点击li元素时,li元素会触发事件冒泡到达父元素,则触发对应事件;同时点击ul也是一样。
功能:只点击li才会发生效果
event事件提供了target属性,target永远表示当前事件的dom,即当前的事件,不是冒泡到的事件。
var ulList = document.getElementById("ul_list");
ulList.onclick = function (e) {
// console.log(e)
var e = e || window.event;
var target = e.target || e.srcElement;
if (target.nodeName === 'LI') {
alert("触发li弹窗事件" + target.innerHTML)
}
}
每个操作都不相同
- 111
- 222
- 333
- 444
var li1 = document.getElementById("li1")
var li2 = document.getElementById("li2")
var li3 = document.getElementById("li3")
var li4 = document.getElementById("li4")
li1.onclick = function(){
console.log("this is li1!")
}
li2.onclick = function(){
console.log("this is li2!")
}
li3.onclick = function(){
console.log("this is li3!")
}
li4.onclick = function(){
console.log("this is li4!")
}
每个操作都不相同的事件委托
var ulList = document.getElementById("ul_list");
ulList.onclick = function (e) {
var e = e || window.event;
var target = e.target || e.srcElement;
if (e.target.nodeName === "LI") {
switch (target.id) {
case 'li1':
console.log("this is li1!")
break;
case 'li2':
console.log("this is li2!")
break;
case 'li3':
console.log("this is li3!")
break;
case 'li4':
console.log("this is li4!")
break;
}
}
}
只进行一次dom操作即可实现对应效果。
对于新增节点:
var btn = document.getElementById("btn");
var ulList = document.getElementById("ul_list");
var liList = ulList.getElementsByTagName('li');
var num = liList.length;
//鼠标悬浮改变颜色,移除变回白色
for (var i = 0; i < liList.length; i++) {
liList[i].onmouseover = function () {
this.style.background = 'lightBlue';
};
liList[i].onmouseout = function () {
this.style.background = '#fff';
};
}
//添加新节点
btn.onclick = function () {
num++;
var newLi = document.createElement('li');
newLi.innerHTML = 111 * num;
ulList.appendChild(newLi);
};
新增节点没有效果节点对应的事件效果。
那么改变方式仍然是用事件委托,在父节点上添加事件。
var btn = document.getElementById("btn");
var ulList = document.getElementById("ul_list");
var liList = ulList.getElementsByTagName('li');
var num = liList.length;
//鼠标悬浮改变颜色,移除变回白色
ulList.onmouseover = function (e) {
var e = e || e.srcElement;
var target = e.target || e.srcElement;
if (target.nodeName === "LI") {
target.style.background = 'lightBlue';
}
};
ulList.onmouseout = function (e) {
var e = e || e.srcElement;
var target = e.target || e.srcElement;
if (target.nodeName === "LI") {
target.style.background = '#fff';
}
};
//添加新节点
btn.onclick = function () {
num++;
var newLi = document.createElement('li');
newLi.innerHTML = 111 * num;
ulList.appendChild(newLi);
};
本文是学习与分享。欢迎指正。
参考链接:js中的事件委托或是事件代理详解 - 凌云之翼 - 博客园