JAVASCript利用事件委托简化点击事件
当写多个点击事件时我总是会添加很多监听函数,但是利用事件委托后仅需添加父元素的监听函数,在利用冒泡就可以为每个子元素添加监听函数,大大简化了程序
前言
以下是围绕事件委托(事件代理)的一个切换案例,同时补充箭头函数和Element.target
一、事件委托
JavaScript中常用绑定事件的常用技巧,“事件委托”即是把原本需要绑定在子元素的响应事件(click、keydown…)委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。
但注意:使用“事件委托”时,并不是说把事件委托给的元素越靠近顶层就越好。事件冒泡的过程也需要耗时,越靠近顶层,事件的”事件传播链”越长,也就越耗时。如果DOM嵌套结构很深,事件冒泡通过大量祖先元素会导致性能损失。
二、箭头函数
箭头函数是ES6新增用于定义函数表达式的函数
首先说明:箭头函数不能使用argument、super和new.target,也不能用作构造函数,没有prototype属性(下节讲)
let arrowSum = (a,b) =>{
return a + b;
}
//等价于
let functionExpressionSum = funtion(a,b){
return a + b;
}
- 如果只有一个参数可以不使用括号
let double = x =>{
return 2*x}
没有参数或者有多个参数,要使用括号(x)
- 如果不使用函数大括号可以进行赋值操作
let value = {
};
let setName = (x) => x.name ="Matt";
setName(value);
console.log(value.name); //"Matt"
- 如果返回一个对象,需要特别注意,如果是单表达式要返回自定义对象,不写括号会报错,因为和函数体的{ … }有语法冲突。
注意,用小括号包含大括号则是对象的定义,而非函数主体
x => {
key: x} // 报错
x => ({
key: x}) // 正确
- 箭头函数内部的this是词法作用域,由上下文确定.(词法作用域就是定义在词法阶段的作用域。换句话说,词法作用域是由你在写代码时将变量和块作用域写在哪里来决定的,因此当词法分析器处理代码时会保持作用域不变)
补充一下词法作用域:其中词法作用域规则如下
1只有函数可以限定作用域 2 函数允许访问函数外部父级作用域的数据
3 变量提升规则 4 就近原则
三、Element.target
兼容性写法
var event = e || window.event;
var tar = event.target || event.srcElement;
target和currentTarget
- target:触发事件的某个具体对象(具体到子元素)。
- currentTarget:绑定事件的对象,恒等于this(非ie的dom2级事件中,ie事件中this指向window),可能出现在事件流的任意一个阶段中。
但在父子嵌套的关系中,父元素绑定了事件,单击了子元素(根据事件流,在不阻止事件流的前提下他会传递至父元素,导致父元素的事件处理函数执行),这时候currentTarget指向的是父元素,因为他是绑定事件的对象,而target指向了子元素,因为他是触发事件的那个具体对象(this是个重点)
四、实例
把四个button放在父元素div里,利用事件委托,对父元素添加点击事件
事件委托代码如下:
var img = document.querySelector('.picbox img');
var butbox = document.getElementById('butbox')
butbox.addEventListener('click', (event) => {
var target = event.target;
switch (target.id) {
case 'buttonone':
img.src = '../html/images/1.webp'
break;
case 'buttontwo':
img.src = '../html/images/2.webp'
break;
case 'buttonthree':
img.src = '../html/images/3.jpg'
break;
case 'buttonfour':
img.src = '../html/images/4.webp'
break;
}
});
在事件委托中一定要注意:只用读父元素的节点
总结
提示:这里对文章进行总结:世界委派可以简化点击事件,箭头函数可以简化函数