今天我们来简单讲一下关于事件绑定与事件委托
举个简单的例子
html代码如下:
<html>
<body>
<div id="buttons">
<button>弹出弹框</ button>
</div>
<button>创建一个新的按钮</button>
</body>
</html>
我们想实现一个点击按钮就能实现弹出一个弹框,另外还有一个按钮用于创建新按钮,
这是小编我一开始犯错的js代码
window.onload = function(){
function1();
}
function function1(){
var div = document.getElementById("buttons");
var button = div.getElementsByTagName("button");
var add = document.getElementById("add");
//添加按钮
add.onclick = function(){
//创建新按钮
var newbutton = document.createElement("button");
newbutton.innerHTML = "点击生成一个新的button";
buttons.appendChild(newbutton);
};
//为每个按钮添加事件
for(var i=0;i<button.length;i++){
button[i].onclick = function(){
alert("有个大傻逼");
}
}
}
点击“添加按钮”,看到成功生成了一个新按钮
点击第一个按钮也出现弹框
一切看似正常,但是当我想点击刚刚生成的按钮的时候就会发现,他并没有我预想的那样也弹出弹框,于是我简单粗暴的给每一个新加的元素重新绑定以个一样的点击事件
function function1(){
var div = document.getElementById("buttons");
var button = div.getElementsByTagName("button");
var add = document.getElementById("add");
//添加按钮
add.onclick = function(){
//创建新按钮
var newbutton = document.createElement("button");
newbutton.innerHTML = "点击生成一个新的button";
newbutton.onclick = function(){
alert("有个大傻逼");
};
buttons.appendChild(newbutton);
};
//为每个按钮添加事件
for(var i=0;i<button.length;i++){
button[i].onclick = function(){
alert("有个大傻逼");
}
}
}
再点击看看,效果出来了
那有没有更好的办法不用我们才重新写一个事件绑定呢,答案是肯定的,这时候我们用到的就是事件委托,顾名思义事件委托就是将原本要发生的事情委托给别的元素,就好比你托别人帮你拿一下快递一样。
这时候我们的js可以这样写:
function function1(){
var div = document.getElementById("buttons");
var button = div.getElementsByTagName("button");
var add = document.getElementById("add");
//添加按钮
add.onclick = function(){
//创建新按钮
var newbutton = document.createElement("button");
newbutton.innerHTML = "点击生成一个新的button";
};
buttons.appendChild(newbutton);
};
//用事件委托为每个按钮添加事件
div.onclick = function(e){
var e = e||window.event;
var target = e.target;
if(target.tagName == "BUTTON"){
alert("有个大傻逼");
}
};
}
事件绑定与事件委托的区别
在说这个之前我们需要知道另外两个概念:事件捕获和事件冒泡
事件捕获:
事件首先发生子啊DOM树的最高层对象(document)然后往最深的元素传播(document–>html–>body–>div)。
事件冒泡:
事件触发的最深层元素首先接收事件,然后是它的父元素,依次向上直到document对象最终接收到的事件(div–>body–>html–>document)。
JavaScript的事件其实带着这个属性,当程序捕获一个事件时,他会知道这个事件来自于页面上的哪一个元素,并逐级向上传递,事件委托就是利用这个原理,父级元素能够知道事件发生在其某个子元素上。
回到问题上来
顾名思义事件绑定就是为每一个元素绑定一个事件,所以我们新添加的元素必须给他绑定事件;而事件委托则是将由来需要执行的事件委托给别人例如下面这行代码,他就是将事件委托给了父级元素div.onclick = function(e)
,由父元素来监听这个事件,然后我们在判断事件发生的位置if(target.tagName == "BUTTON")
,只要符合要求就能够实现alert("有个大傻逼");
从去网上查到的资料得知:在IE8及其更低的版本中,大于等于10000个元素时,会有“假死”现象,在元素数量比较大时,事件委托效率明显高事件绑定,而且占用的内存会比较低。
有同学可能会说这样的话我事件委托直接全部交个document就行了嘛。这样可能会导致事件的“传播链”太长,导致性能损失。