JS之事件委托
事件委托作为js事件中一种别致的触发事件方式,在JS的程序设计中有着不可或缺的作用,而且事件委托的存在让很多需要进行负责处理的案例变得容易了许多,尤其适用于有动态元素存在的案例中,接下来我们具体来聊聊事件委托到底是什么。
顾名思义,委托就是把一个人的事情委托在另一个人的身上,委托事件也是一样,我们知道JS中事件传播时会有冒泡和捕获,事件委托正是利用了实际按冒泡这一原理来实现的。
简单来说,事件委托就是把要发生在子元素身上的事件委托在父元素的身上,这样即使子元素不存在,委托在父元素身上的委托事件依旧可以存在,这样做有什么作用呢?
接下来我们看代码
<body>
<button id="btn">点我一下试试</button>
<script>
//获取按钮
var btn_ele = document.getElementById("btn");
//给document委托事件
document.addEventListener("click" , function(evt){
//获取事件对象
var e = evt || event;
//获取事件目标
var target = e.target || e.srcElement;
//判定是否点击到了目标元素
if(target === btn_ele){
alert("我是目标元素");
}
} )
</script>
</body>
我们来看一下运行效果:
当我们点击页面按钮之外的部分时,页面中不会弹出提示框
当我们点击页面按钮时的部分时,页面中弹出了提示框
根据代码来看。我们并没有给按钮添加点击事件,但为什么浏览器中出现了提示框呢?原因很简单,是因为我们把点击事件委托到了document之中,根据代码我们有必要解释一下target是什么。
根据代码可知,我们首先获取了事件对象,然后定义了target变量。Target是事件目标,通俗点说就是告诉我们在docum里面点击了哪个元素,再看一段代码
<body>
<button id="btn">点我一下试试</button>
<button id="btn_right">再点我一下</button>
<script>
document.addEventListener("click" , function(evt){
//获取事件对象
var e = evt || event;
//获取事件目标
var target = e.target || e.srcElement;
//判定是否点击到了目标元素
console.log(target);
} )
</script>
</body>
执行代码之后。我们从左至右依次点击左边的按钮,右边的按钮,浏览器窗口,然后我们得到了以下的打印结果
由打印出来的结果我们知道,我们点击到谁身上,那么target就是谁,并且结果是一个具体且完整的标签,所以在事件委托中,我们可以利用target控制去判断元素,当我们所希望发生事件的元素与当前target对应时,我们就可以从众多元素中选出我们想要操作的元素。
我们可以利用这些特性来实现一种动态元素创建的效果,直接看代码
<body>
<button id="btn">点我一下试试</button>
<script>
document.addEventListener("click" , function(evt){
//获取事件对象
var e = evt || event;
//获取事件目标
var target = e.target || e.srcElement;
//判定是否点击到了目标元素
if(target.nodeName === "BUTTON"){
//创建一个标签
var button = document.createElement("button");
button.innerHTML = "我是生成的按钮";
document.body.appendChild(button);
}
} )
</script>
</body>
我们来简单分析一下上述代码,首先我们把事件委托给document,然后在监听器中判断是否点击到的元素是标签名为button的元素,如果判断成功,那么我们创建一个新的button标签,并且添加进去内容,最后传入到页面结构中,所以预想到的结果是我们点击标签会生成标签,依次类推。
我们发现在每点击一次就会生成一个按钮,点击生成好的按钮也会生成按钮,大家可以自行进行测试。
这样与直接给第一个元素添加点击事件然后在点击事件中生成按钮有区别吗?答案是有,如果我们只给第一个标签添加点击事件,那么点击事件只会在我们绑定了事件的这个元素上触发,而不会在新生成的元素上触发。
事件委托多用在子元素中有重复的动态生成元素案例中(元素类似),如果有特殊区别的子元素,那么事件委托的效果就微乎其微了,事件委托的实用性大家可以去慢慢发掘。