事件冒泡应用:事件代理

事件冒泡应用:事件代理

1. 什么是事件代理

事件代理,应用了事件冒泡的特性,将一个元素的事件处理,交给祖先元素进行处理。即,自己本身不处理事件,而是通过冒泡的特性,触发祖先元素的相同事件,调用祖先元素的回调函数。

2. 事件代理的实现

回看之前为了总结知识,做的一个小练习*点击查看→示例代码:选电影票*

其中,有这样的一段代码:


		//创建一个元素(对象),表示已经选择的票
		var selectedBtn = document.createElement("button");
		
		...(忽略这些代码)

		//绑定回调函数
		selectedBtn.onclick = cancelSelected;
		//记录对应的票
		selectedBtn.ticket = ticket;
		//渲染
		selected.appendChild(selectedBtn);

解释:每当单击一个未选择的座位(选票操作),就会在“已经选择”的区域产生一个提示的“标签”,点击这个“标签”可以取消对票的选择。在上面的例子中,每选择一张票,就会生成一个“标签”,并且给这个“标签”绑定一个响应函数(取消选择)。

给祖先元素(一般使用父元素)绑定回调函数(响应函数)

上面的例子中这里的事件全都自己处理,现在要将这些事件,委托给父元素处理

	//获取父元素
	let selected = document.getElementById("selected");
	//给父元素绑定响应函数
	selected.onclick = cancelSelected;

之前没有委托给祖先元素处理时,回调函数的隐式参数this为事件的触发者;现在,委托给祖先元素后,隐式参数this是祖先元素本身。又有新的问题出现了怎么获取事件的触发者

在祖先元素的响应函数中,获取事件的触发者:Event.target

事件对象中有一个target属性,Event.target,表示事件的触发者,这样,就可以在祖先元素的响应函数中获取触发事件的后代元素

/**委托给父元素的响应函数	
 * @param {Object} event 事件对象
 */
function cancelSelected(event){
	//获取触发事件的元素
	let target = event.target;
	//修改座位状态为未选中
	target.seat.selected = false;
	//修改总价格
	var totalPrice = document.getElementById("totalPrice");
	let money = Number(totalPrice.innerHTML);
	totalPrice.innerHTML = money - target.ticket.price;
	//删除结点
	target.parentNode.removeChild(target);
	//修改座位颜色
	target.seat.style.backgroundColor = "rgb(239, 239, 239)"
}

避免父元素本身触发事件

现在,基本功能已经实现,但是有一个BUG。如果现在单击父元素,就会出现错误,现在的target === thistarget不是子元素。

解决方式一:判断target === this,如果为true,就表示触发事件的是祖先元素,事件处理函数字节返回,不执行任何操作。


function cancelSelected(event){
	//获取触发事件的元素
	let target = event.target;
	if(this === target)
	return ;
					
	...(后代元素触发事件后,要处理的操作)		
}

解决方式二:根据html标签名判断是否为子元素。子元素是一个button元素,对应的tagNameBUTTON,只需要判断触发事件的对象target的标签名是否为BUTTON,即可区分它和祖先元素。

关键点:代理对象(祖先)和被代理对象(后代)的标签名不能一样

function cancelSelected(event){
	//获取触发事件的元素
	let target = event.target;
	
	if(target.tagName !== "BUTTON")
		return ;
}

除了上述两种解决方式,还可以通过cssclass属性来判断。通过target.className可以获取。通过class来判断时,要注意可能会有多个空格间隔的字符串,因此可以使用正则表达式进行判断。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值