addEventListener 执行多次的问题

我做了一个弹窗,结果每点一次确认按钮,回调方法都会多执行一次

var msg = {
        dialog:function(){
            var dialogEl  = document.querySelector('.dialog');
            var queding_bt  = document.querySelector('.queding');

            dialogEl.style.display = 'block';
            queding_bt.addEventListener('click', function(){
                //确定后执行
                alert(111);
                dialogEl.style.display = 'none';
            })
        }
    }

示例,点这儿。。。

尝试过,把元素声明放到msg对象的属性上,也试过removeEventListener,都不起作用。

阅读 13.2k
3 个回答
queding_bt.addEventListener('click',
    function(){
                //确定后执行
                alert(111);
                dialogEl.style.display = 'none';
            },{once: true})

https://developer.mozilla.org...


关于执行多次的问题是在元素多次注册事件监听器造成的

首先要明确一点,在元素上重复注册相同的事件监听器,多余的监听器会被移除,只保留一个
问题在于你这段代码的回调函数是一个匿名函数,那么这就导致了你每一次注册都是一个不同的事件监听器。
这就导致了事件多次注册,当你运行一次msg.dialog()就在queding_bt上注册一次。
当你把匿名函数提出去,用一个声明的函数作为回调的话就没问题了。

代码如下

    // 声明函数
    function test() {
        var dialogEl = document.querySelector('.dialog');
        alert(111);
        dialogEl.style.display = 'none';
    }
    var msg = {
        dialog: function() {
            var dialogEl = document.querySelector('.dialog');
            var queding_bt = document.querySelector('.queding');

            dialogEl.style.display = 'block';
            queding_bt.addEventListener('click', test)

        }
    }

<div style="width:100px; height:20px;" onclick='msg.dialog()'>点这</div>
每次点击此元素,就会执行一次msg.dialog(),弹窗就会多添加一个监听事件,
var queding_bt = document.querySelector('.queding');
queding_bt.addEventListener('click', function(){

            //确定后执行
            alert(111);
            dialogEl.style.display = 'none';
        })
        
        把此段代码拿出来放在dialog()外面就好了
        
var msg = {
        dialog:function(){
            var dialogEl  = document.querySelector('.dialog');
            var queding_bt  = document.querySelector('.queding');

            dialogEl.style.display = 'block';
            queding_bt.addEventListener('click', function listen(){
                //确定后执行
                alert(111);
                dialogEl.style.display = 'none';
                queding_bt.removeEventListener(listen)
            })
        }
    }

每次用完卸载掉。

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