js事件不同写法的处理方式是什么?

学习js事件时,有三种不同的写法,
第一种

<button id="btn" onclick="aa(dianji(),1000)">点击</button>
<script>
 function dianji() {  
        console.log("点击")
    }
    // 防抖
    function aa(fn, delay) {
        let timer = null
        // console.log(timer)
        return function () {
            if (timer) {
                clearTimeout(timer)
            }
            timer = setTimeout(fn, delay)
        }
    }
</script>

第二种

<button id="btn" >点击</button>
<script>
    function dianji() {
        
        console.log("点击")
       
    }
    // 防抖
    function aa(fn, delay) {
        let timer = null
        // console.log(timer)
        return function () {
            if (timer) {
                clearTimeout(timer)
            }
            timer = setTimeout(fn, delay)
        }
    }
    let a = document.getElementById("btn")
    a.onclick = aa(dianji, 1000);
    
    // console.log(timer)
</script>

第三种

 <button id="btn" >点击</button>
<script>
    // 节流
    function aa1(fn,delay){
        let valid = true;
        return function(){
            if(!valid){
                return  false;
            }
            valid = false;
            setTimeout(function(){
                fn();
                valid = true;
            },delay)
        }
    }
    function dianji() {
        
        console.log("点击")
       
    }
    // 防抖
    function aa(fn, delay) {
        let timer = null
        // console.log(timer)
        return function () {
            if (timer) {
                clearTimeout(timer)
            }
            timer = setTimeout(fn, delay)
        }
    }
    let a = document.getElementById("btn")
    // a.onclick = aa(dianji, 1000);
    a.addEventListener("click",aa(dianji,1000))
    
    // console.log(timer)
</script>

我想实现一下点击事件的防抖效果,但是直接在button标签中加点击事件没有效果。
第一个问题:第一种写法哪里有问题?应该怎么改正?
第二个问题:这三种写法是不是在运行的时候有区别?区别是什么?
希望有人解答一下

阅读 1.3k
avatarAI BotBETA

第一种写法的问题

在你的第一种写法中,onclick 属性中的函数 aa(dianji(),1000) 执行时,dianji() 函数并没有传入任何参数。而在你的 dianji 函数定义中,你并没有声明接受任何参数,所以当没有传递参数给 dianji 函数时,JavaScript 会抛出一个错误。

要改正这个问题,你可以修改 dianji 函数以接受一个参数,或者在 aa 函数中传递一个参数给 dianji 函数。下面是一个修改的例子:

<button id="btn" onclick="aa(dianji,1000)">点击</button>

<script>
    function dianji(x) {  
        console.log("点击,参数是:" + x);
    }
    // 防抖
    function aa(fn, delay) {
        let timer = null;
        return function (x) {
            if (timer) {
                clearTimeout(timer);
            }
            timer = setTimeout(function() {
                fn(x);
            }, delay);
        }
    }
</script>

这三种写法的区别

这三种写法的主要区别在于何时和如何调用 dianji 函数。

  • 在第一种写法中,dianji 函数在 HTML 元素被加载后立即被调用,然后它的返回值(如果是一个函数)或者 undefined(如果不是一个函数)被传递给 aa 函数。然后,当用户点击按钮时,aa 函数将再次被调用,并传递按钮的点击事件作为参数。
  • 在第二种写法中,dianji 函数在 HTML 元素被加载后立即被调用,并立即绑定到元素的 onclick 事件。当用户点击按钮时,dianji 函数将被调用。这种写法与第一种写法的区别在于,aa 函数在这里被直接绑定到 onclick 事件,而不是在 onclick 事件发生时被调用。
  • 在第三种写法中,dianji 函数在用户点击按钮后被调用。这是通过使用事件监听器实现的,而不是直接在 HTML 元素上设置 onclick 属性。这种写法可以让你有更多的控制权,比如可以添加多个监听器,或者在监听器被触发时执行额外的操作。此外,使用事件监听器通常是更现代和更推荐的 HTML DOM 事件处理方式。

希望这个答案对你有所帮助!如果你还有其他问题,欢迎随时提问。

4 个回答

onclick="aa(dianji(),1000)",你的aa函数第一个参数需要的是一个函数,而你的写法带()指运行dianji这个函数,把函数返回值传给aa,把dianji传给aa应该写成onclick="aa(dianji,1000)"

没啥区别,都是事件绑定,硬说区别,就是addEventListener较前两种可以绑定多次

第一个问题:
参照AI和其他人的回复。

第二个问题:
addEventListener使用事件监听器(事件委托)实现。

  1. 可以添加多个监听器;
  2. 如果HTML内容是动态加载的,这种方法也可以正常绑定事件。

一般来说,更推荐这种方法。

第一种 内联事件 和第二种 事件句柄 的方式都只能绑定单一的事件
第三种,可以看下MDN上对 addEventListener 的描述,简单总结就是

  • 可以绑定多个事件
  • 可以通过第三个参数更精细的控制事件的行为,比如事件在什么阶段执行,是否只执行一次等等
  • 可以绑定HTML,SVG元素之外的事件

在工作原理上, 内联事件事件句柄 底层都是调用的 addEventListener 进行事件注册,前两者其实就是提供了一种相对 addEventListener 稍微简洁一点的事件绑定方式

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题