【WEB开发.js】addEventListener事件监听器的绑定和执行次数的问题(小心踩坑)

假设我们有一个按钮,用户点击该按钮后,会选择一个文件,且我们希望每次点击按钮时只触发一次文件处理。下面我会给你一个简单的例子,展示放在函数内部和放在函数外部的区别。

1. 将事件监听器放在函数内部(问题的根源)

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>事件监听器放在函数内部</title>
</head>
<body>
    <button onclick="onclickbtnLoadMainLVDS()">点击选择文件</button>
    <input type="file" id="id_file_loadLVDS" style="display:none">
    <script>
        function onclickbtnLoadMainLVDS() {
            document.getElementById('id_file_loadLVDS').click();  // 点击按钮时触发文件选择

            const fileInput = document.getElementById('id_file_loadLVDS');
            // 每次点击按钮时,都给文件输入框绑定事件监听器
            fileInput.addEventListener('change', function(e) {
                console.log('文件被选择了');
            });
        }
    </script>
</body>
</html>

问题:

  • 在这个例子中,每次点击按钮时,我们都会调用 onclickbtnLoadMainLVDS 函数。
  • 每次函数调用时,都为 input 元素绑定了一个新的 change 事件监听器。
  • 如果你点击按钮 多次 ,那么就会为同一个文件输入框绑定 多个监听器
  • 这样,当用户选择文件时,事件会触发 多个监听器,导致相同的事件处理逻辑执行多次。

例如,点击按钮两次会绑定两个监听器,再选择文件时,控制台会输出两次 "文件被选择了"

2. 将事件监听器放在函数外部(解决问题)

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>事件监听器放在函数外部</title>
</head>
<body>
    <button onclick="onclickbtnLoadMainLVDS()">点击选择文件</button>
    <input type="file" id="id_file_loadLVDS" style="display:none">
    <script>
        // 在函数外部绑定一次事件监听器
        const fileInput = document.getElementById('id_file_loadLVDS');
        fileInput.addEventListener('change', function(e) {
            console.log('文件被选择了');
        });

        function onclickbtnLoadMainLVDS() {
            document.getElementById('id_file_loadLVDS').click();  // 点击按钮时触发文件选择
        }
    </script>
</body>
</html>

解决问题的方式:

  • 在这个例子中,我们 只在页面加载时 就绑定了一个 change 事件监听器。
  • 无论按钮点击多少次,事件监听器始终只会绑定一次。
  • 这样,每次用户选择文件时,事件只会触发 一次,无论按钮点击多少次。

总结

  • 函数内部绑定事件监听器的坏处:每次点击按钮时都重新绑定事件监听器,导致事件处理程序被多次调用。如果你点击按钮很多次,事件监听器会被重复绑定,最终导致每次文件选择触发多个事件处理。
  • 函数外部绑定事件监听器的好处:事件监听器只会绑定一次,无论用户点击多少次按钮,文件选择时只会触发一次处理程序。

解决方案

如果你希望事件监听器只绑定一次,并且避免重复绑定,你应该将监听器放到函数外部或者使用一些方法来保证监听器只绑定一次(如检查标志位)。

相关推荐
奔跑吧邓邓子3 分钟前
【Python爬虫(34)】Python多进程编程:开启高效并行世界的钥匙
开发语言·爬虫·python·多进程
Heris9930 分钟前
2.22 c++练习【operator运算符重载、封装消息队列、封装信号灯集】
开发语言·c++
----云烟----32 分钟前
C/C++ 中 volatile 关键字详解
c语言·开发语言·c++
yuanpan1 小时前
23种设计模式之《组合模式(Composite)》在c#中的应用及理解
开发语言·设计模式·c#·组合模式
BanLul1 小时前
进程与线程 (三)——线程间通信
c语言·开发语言·算法
十八朵郁金香1 小时前
【JavaScript】深入理解模块化
开发语言·javascript·ecmascript
m0_748230941 小时前
Redis 通用命令
前端·redis·bootstrap
Hello.Reader1 小时前
深入理解 Rust 的 `Rc<T>`:实现多所有权的智能指针
开发语言·后端·rust
程序员阿鹏1 小时前
jdbc批量插入数据到MySQL
java·开发语言·数据库·mysql·intellij-idea
yoona10201 小时前
Rust编程语言入门教程(八)所有权 Stack vs Heap
开发语言·后端·rust·区块链·学习方法