如何避免重复addEventListener?

本文探讨了如何确保JavaScript事件监听器的唯一性,避免重复添加。通过将处理函数保存为元素属性的方式,实现了对同一元素多次绑定同一事件时的处理函数唯一化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

避免重复addEventListener的核心就是在添加前通过removeEventListener将已经添加的处理函数进行移除。如下代码为id=btn的元素添加click事件的处理函数clickHandler

const $btn = document.getElementById('btn');
function clickHandler() {
	console.info(`this is in clickHandler`);
}

$btn.removeEventListener('click', clickHandler);
$btn.addEventListener('click', clickHandler);

但是在这里涉及到一个问题,JavaScript中函数是引用类型,因此在进行removeEventListener时,第二个参数需要和addEventListener时的引用相同,否则无法达到移除的效果。如下代码所示:

Html部分代码如下

<body>
<h1 id="btn">click here</h1>

<section>
    <button onclick="addListener()" id="btnForBtn">add handler for click here</button>
</section>

JavaScript代码如下

const $btn = document.getElementById('btn');

let count = 0;

function addListener() {
	function clickHandler() {
	    console.info(`this is in clickHandler but created ${++count} times`);
	}

	$btn.removeEventListener('click', clickHandler);
	$btn.addEventListener('click', clickHandler);
}

效果图,如下:
这里写图片描述

点击add handler to click here按钮为click here按钮添加点击事件,并在添加前进行移除,希望达到唯一处理函数的效果。右侧输出展示的是六次add handler to click here按钮点击,一次click here按钮点击的效果。可以看到,并未达到预期。原因是:每次执行函数addListener都重新创建了clickHandler函数,因此在进行removeEventListener时并未将原有的处理函数进行移除

如果将clickHandler移动到addListener函数之外仅进行一次定义,那么是可以达到唯一添加的效果,但是在有些业务需求中需要进行如此类代码结构的编写方式(如Vue中,在directive的各生命周期中进行事件绑定)。而此时为了达到唯一绑定的效果,其实就是保存clickHandler的唯一引用的问题。如果不能提取到外部作为全局变量,那么换个思路,作为待绑定元素的属性也就可以了,JavaScript代码如下:

const $btn = document.getElementById('btn');

let count = 0;

function addListener() {
	if ($btn.clickHandler) {
		$btn.removeEventListener('click', $btn.clickHandler);
	}

	$btn.clickHandler = () => {
		console.info(`this is in clickHandler but created ${++count} times`);
	};

	$btn.addEventListener('click', $btn.clickHandler);
}

效果图,如下:
这里写图片描述

这里需要注意的是:

  1. 过多的在元素上绑定属性,有可能会造成性能的损耗和增加维护的成本
  2. clickHandler属性的定义应该进行命名空间的限制,以避免发生同名属性覆盖的问题

最后需要提到的是,对同一个元素的同一个事件重复进行处理函数的添加,是只生效一次的,如下代码中:

const $btn = document.getElementById('btn');

const clickHandler = () => {
	console.info('this is handler1')
};

// 多次添加同一个事件处理函数,则不会重复执行
$btn.addEventListener('click', clickHandler);
$btn.addEventListener('click', clickHandler);

在页面中对$btn元素进行点击,clickHandler将只执行一次。

学艺不足,欢迎各位看官纠正指错,祝各位生活愉快,工作顺利~~

智能网联汽车的安全员高级考试涉及多个方面的专业知识,包括但不限于自动驾驶技术原理、车辆传感器融合、网络安全防护以及法律法规等内容。以下是针对该主题的一些核心知识点解析: ### 关于智能网联车安全员高级考试的核心内容 #### 1. 自动驾驶分级标准 国际自动机工程师学会(SAE International)定义了六个级别的自动驾驶等级,从L0到L5[^1]。其中,L3及以上级别需要安全员具备更高的应急处理能力。 #### 2. 车辆感知系统的组成与功能 智能网联车通常配备多种传感器,如激光雷达、毫米波雷达、摄像头和超声波传感器等。这些设备协同工作以实现环境感知、障碍物检测等功能[^2]。 #### 3. 数据通信与网络安全 智能网联车依赖V2X(Vehicle-to-Everything)技术进行数据交换,在此过程中需防范潜在的网络攻击风险,例如中间人攻击或恶意软件入侵[^3]。 #### 4. 法律法规要求 不同国家和地区对于无人驾驶测试及运营有着严格的规定,考生应熟悉当地交通法典中有关自动化驾驶部分的具体条款[^4]。 ```python # 示例代码:模拟简单决策逻辑 def decide_action(sensor_data): if sensor_data['obstacle'] and not sensor_data['emergency']: return 'slow_down' elif sensor_data['pedestrian_crossing']: return 'stop_and_yield' else: return 'continue_driving' example_input = {'obstacle': True, 'emergency': False, 'pedestrian_crossing': False} action = decide_action(example_input) print(f"Action to take: {action}") ``` 需要注意的是,“橙点同学”作为特定平台上的学习资源名称,并不提供官方认证的标准答案集;建议通过正规渠道获取教材并参加培训课程来准备此类资格认证考试。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值