匿名函数是否能够处理removeEventListener?

时间:2016-04-15 02:19:53

标签: javascript

考虑以下示例。我们有一个简单的html文件

<body>
    <button id="button" type="button" onclick="create_button()">Create button</button>
</body>

和两个版本的js文件。版本。一个:

function create_button() {
    var new_button = document.createElement("Button");
    new_button.innerHTML = "Pop the alert";
    new_button.type = "button";
    new_button.addEventListener('click', function () { my_function("you") });
    new_button.removeEventListener('click', function () { my_function("you") });
    document.body.appendChild(new_button);
};

function my_function(x) {
    alert("I like " + x);
};

和ver。 B:

function create_button() {
    var new_button = document.createElement("Button");
    new_button.innerHTML = "Pop the alert";
    new_button.type = "button";  
    function helper() {
        my_function("you");
    };
    new_button.addEventListener('click', helper );
    new_button.removeEventListener('click', helper );
    document.body.appendChild(new_button);
};

function my_function(x) {
    alert("I like " + x);
};

前者不起作用(实际上removeEventListener不起作用)而后者不起作用。

所以我问匿名函数是否存在问题,或者是否存在阻止第一代码正常执行的基本方面。

2 个答案:

答案 0 :(得分:2)

  

要删除事件处理程序,使用addEventListener()方法指定的函数必须是外部函数,...   匿名函数,例如&#34; element.removeEventListener(&#34; event&#34;,function(){myScript});&#34;不行。

http://www.w3schools.com/jsref/met_element_removeeventlistener.asp

注意:对于那些反w3schoolers,我知道答案,但无法在MDN中找到适当的参考。

答案 1 :(得分:1)

简而言之,你不能使用removeEventListener的匿名函数,但值得知道原因。

在第一个实现中,您将事件侦听器添加为匿名函数,然后立即删除事件侦听器(使用完全相同的代码)。但是,即使您添加/删除的侦听器函数具有相同的代码,它们也被视为2个完全独立的函数,因为它们是。你已经定义了一个函数两次,所以即使两个函数具有相同的实现,它们在内存中也有不同的引用ID,并且根本没有相互关联。

在第二个(工作)实现中,您只需定义一次函数,然后在添加和删除侦听器时定义引用。这意味着在内部,JS引擎在内存中查看相同的对象(函数也是对象),因此它可以删除添加的原始函数。

所以问题不在于你所使用的函数是匿名的,而是因为这个函数是匿名的,所以当你想要删除它时,没有办法引用它,并且所以你最终试图删除你动态创建的函数,这当然不会起作用,因为该函数从未首先添加到目标元素。

MDN docs on removeEventListener可能会有所帮助。