js中,addEventListener时用的是匿名函数,应该怎么移除事件?

黒之染
  • 3.1k

像下面init()里面那样添加的事件,应该怎么移除?如下的例子是移除不了的,请问还有别的方法吗?

function init(){
    aabtn.addEventListener("click",function(e){aa()});//aabtn是一个div
}
var i = 0;
function aa(){
    tex.innerHTML = i++;//tex也是一个div
    aabtn.removeEventListener("click",arguments.callee);//这样的写法是不行的,请问还有别的写法吗?
}
回复
阅读 14.1k
4 个回答

不要混淆匿名函數和函數表達式。

"use strict";

el.addEventListener("input", function oninput() {
    el.removeEventListener("input", oninput);
});

話說 arguments.callee 就是爲了解決這一問題而出現的,但現在有了函數表達式,arguments 也就沒必要存在了。投奔嚴格模式與未來吧!


模塊化需要的是閉包,而不是什麼匿名函數、函數表達式與函數聲明的寫法。

其實你需要的是這個:

Immediately-invoked function expression:

(function (){
    "use strict";

    function oninput() {
        el.removeEventListener("input", oninput);
    }

    el.addEventListener("input", oninput);
}());

console.log(oninput); // undefined

至於事件處理函數調用時 this 的指向問題(這不叫模塊化,這叫面向對象)

題主需要的是這個:

(function() {
    "use strict";

    var counter = {
        value: 0,
        click: function() {
            console.log("click: " + ++this.value);
        }
    };

    function once(el, ev, fn) {
        el.addEventListener(ev, function handler() {
            fn.apply(this, arguments);
            el.removeEventListener(ev, handler);
        });
    }

    once(window.document, "click", counter.click.bind(counter));
}());

啊哈哈哈,我知道问题出在哪了,也知道 arguments.callee 到底是什么了!原来在函数内,arguments.callee 是指本函数,也就是函數自身,所以以下会在控制台输出函數 aa(toString 後也就是函數的代碼)。

(function aa() {
    console.log(arguments.callee);
}());

而我要的函数不是这个,而是绑定到 click 的函数,所以代码应该改成这样:

var i = 0;

function init() {
    aabtn.addEventListener("click", function(e) { aa(arguments.callee); });
}

function aa(fun) {
    tex.innerHTML = i++;
    aabtn.removeEventListener("click", fun);
}

何必多此一举,你原本的代码改成

aabtn.addEventListener("click",aa);

就可以了

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

宣传栏