removeEventListener不适用于动态分配的元素

问题描述 投票:0回答:2

我不明白为什么div1元素在点击div2元素后仍然分配了事件监听器。似乎specialFunction()div参数是div1元素在初始执行后和点击div2之后应该从div1中删除监听器,但它没有。

谢谢你的建议。

let div1 = document.createElement("div");
div1.innerHTML = "div1"
document.body.appendChild(div1);

let div2 = document.createElement("div");
div2.innerHTML = "div2";
document.body.appendChild(div2);

specialFunction(div1, false);

div2.addEventListener("click", function()
{
    console.log("div2 clicked");
    specialFunction(div1, true);
});

function specialFunction(div, remove)
{
    function divFunc()
    {
        console.log("div1 clicked");
    }
    
    if(remove)
        div.removeEventListener("click", divFunc);
    else
        div.addEventListener("click", divFunc);
}
div{ height: 50px; border: 1px solid black; }
javascript dynamic element event-listener
2个回答
1
投票

亲爱的朋友你的问题是:divFunc()的地方,这个函数是localFunction()的本地函数,第二次你调用这个函数,做一个新的。并且新的函数对象不等于最后一个!

试试这个:

let div1 = document.createElement("div");
div1.innerHTML = "div1";
document.body.appendChild(div1);

let div2 = document.createElement("div");
div2.innerHTML = "div2";
document.body.appendChild(div2);

specialFunction(div1, false);

div2.addEventListener("click", function () {
    console.log("div2 clicked");
    specialFunction(div1, true);
});
function divFunc() {
    console.log("div1 clicked");
}
function specialFunction(div, remove) {


    if (remove)
        div.removeEventListener("click", divFunc);
    else {
        hnd = div.addEventListener("click", divFunc);
        console.log(hnd)
    }
}

0
投票

Loop approach

对于那些在循环中创建元素的人:

// I suggest to run this code on full page...
    for(let i = 1; i<=5; i++)
    {
        let div = document.createElement("div");
        div.innerHTML = "div "+i;
        document.body.appendChild(div);

        let removeEvent = document.createElement("span");
        removeEvent.innerHTML = "removeEvent "+i;
        removeEvent.setAttribute("class", "removeEvent");
        div.appendChild(removeEvent);
        
        function divFunc(e)
        {
            console.log(`${div.tagName} ${i} ${e.type}ed ${this.dcp.p1} ${div.dcp.p2()} ${this.dcp.p3[2]} ${div.dcp.p4.json[0]}-${this.dcp.p4.json[1]}`);
        }

        specialFunction(div, false, i, divFunc);

        removeEvent.addEventListener("click", e=>
        {
            e.stopPropagation();
            specialFunction(div, true, i, divFunc);
        });
    }



    function specialFunction(div, remove, i, divFunc)
    {
        div.dcp = { // dynamically created parameters
            p1: "by",
            p2: function(){ return "mouse"; },
            p3: [undefined, null, "with random key:"],
            p4: {json: JSON.parse(`[
                "${Math.random().toString().substring(2,10)}", "${i}"
            ]`)}
        };

        if(remove)
        {
            console.log("removed event "+i);
            div.removeEventListener("click", divFunc);
        }
        else
            div.addEventListener("click", divFunc);
    }
*{ margin: 5px;}
div{ border: 1px solid #000000; padding: 10px;}
.removeEvent{ background: red; border: 1px solid #000000; }
console.log(`${div.tagName} ${i} ${e.type}ed ${this.dcp.p1} ${div.dcp.p2()} ${this.dcp.p3[2]} ${div.dcp.p4.json[0]}-${this.dcp.p4.json[1]}`);

表明您可以轻松地在事件函数内部使用动态创建的内部局部变量,如divi,以及外部div.dcp对象属性。请注意,this.dcp相当于div.dcp

© www.soinside.com 2019 - 2024. All rights reserved.