Javascript只支持最后一个事件监听器

时间:2022-11-05 12:48:50

It's very difficult for me to show you my code, as it's all over the place, but what I'm trying to do is this:

我很难向你们展示我的代码,因为到处都是,但是我想做的是:

I am injecting html code into the DOM in a function buy using .innerHTML, I wish to add a click event to an icon that is being injected in this step, as at this moment in time I know its id. So after I've injected it I write:

我正在用。innerhtml将html代码注入DOM函数buy中,我希望在这个步骤中注入的图标中添加一个单击事件,因为此时我知道它的id。

document.getElementById(product.id+"x").addEventListener("click", removeItem);

. getelementbyid(product.id +“x”)。addEventListener(“点击”,removeItem);

product.id is created above and this element is a 'X' button, that when clicked will be removed from the screen.

产品。id是在上面创建的,这个元素是一个“X”按钮,当单击将从屏幕上删除。

The trouble is, this code is run many times as there are many items to be displayed on the screen. And when finished, only the last even made fires when the 'X' button is pressed.

麻烦的是,由于屏幕上显示了许多项,所以这段代码要运行多次。当完成后,只有最后一个人在按下“X”键时才会开火。

Any suggestions?

有什么建议吗?

EDIT:

编辑:

I am unable to use jquery in this project.

我无法在这个项目中使用jquery。

Here is my code:

这是我的代码:

function createHTML(targetID, product) {
    var target = document.getElementById(targetID);
    total = (parseFloat(total) + parseFloat(product.price)).toFixed(2);;
    target.innerHTML += '<article class="item" id="'+product.id+'"><img class="item_img" src="../'+product.image+'" width=100 height=100><h1 class="item_name">'+product.name+'</h1><p class="item_description">'+product.desc+'</p><h1 class="item_quantity">Quantity: '+product.quantity+'</h1><h1 class="item_price">&pound;'+product.price+'</h1><i id="'+product.id+'x" class="fa fa-times"></i></article>';

    document.getElementById(product.id+"x").addEventListener("click", removeItem, true);
}

2 个解决方案

#1


5  

So you're adding new elements to a container by overwriting the innerHTML or appending to it using +=. This is your problem. When you overwrite the innerHTML or append to it, you are destroying and recreating all elements within it and this causes them to lose any bound event handlers (ie your click handler).

因此,通过重写innerHTML或使用+=添加新元素到容器中。这是你的问题。当您覆盖innerHTML或附加到它时,您正在销毁并重新创建其中的所有元素,这将导致它们丢失任何绑定事件处理程序(即单击处理程序)。

This fiddle reproduces your problem. Only the last button has a click handler.

这只小提琴再现了你的问题。只有最后一个按钮有一个单击处理程序。

The solution is to build DOM elements using document.createElement() and use appendChild() or similar to append them, instead of creating/appending raw HTML. This way, your previous elements event handlers will remain intact.

解决方案是使用document.createElement()构建DOM元素,并使用appendChild()或类似于追加它们,而不是创建/追加原始HTML。这样,您以前的元素事件处理程序将保持不变。

This Fiddle uses DOM nodes instead of raw HTML and all buttons have a click handler.

这个小提琴使用DOM节点代替原始HTML,所有按钮都有一个单击处理程序。

Example fix:

例修复:

var container = document.getElementById("container");
var elem;

function clicky(){
    alert("clicked");   
}

for(var i=0; i<4; i++){
    elem = document.createElement('button');
    elem.id = "btn_" + i;
    elem.appendChild(document.createTextNode('Click'));
    elem.addEventListener("click", clicky);
    container.appendChild(elem);
}

#2


2  

I quess you do something like that

我敢说你是做那种事的

//Place where you add elements.
var container = document.body;

you create element and add listener to that element(button):

创建元素并向该元素(按钮)添加侦听器:

var button = '<button id="btn1x">Button 1</button>';
container.innerHTML += button;

//product.id = 'btn1';
document.getElementById(product.id+"x").addEventListener("click", removeItem);

and then you add in the same way new elements and add for them event listeners before next element will be generated.

然后添加相同的方法,在生成下一个元素之前添加新元素并为它们添加事件监听器。

If my quess is right, then your problem is that you replace whole content of container so previous event listens are lost.

如果我的quess是对的,那么您的问题是您替换了容器的整个内容,从而丢失了以前的事件监听。

stringVariable += 'abc' is the same as stringVariable = stringVariable + 'abc'. Because of that you overwrite html.

stringVariable += 'abc'和stringVariable = stringVariable + 'abc'是一样的。因为这样你就覆盖了html。

You should create elements from functions, not from string as you do now.

应该从函数中创建元素,而不是像现在这样从字符串中创建元素。

var button = document.createElement('button');
button.id = product.id + 'x'; 
button.innerText = 'Button 1'; // Title of button.

//Add button to container.
container.appendChild(button);

//Add event listener to created button.
button.addEventListener('click', myFunc); 

UPDATE:

更新:

There are a way to parse your string to element.

有一种方法可以将字符串解析为元素。

First create container where will be set inner html from string, then get from that temp container first element (or more elements, depends from your html string), then add them to container and add to these elements listeners.

首先创建一个容器,其中将从字符串中设置内部html,然后从temp容器的第一个元素(或更多元素,取决于您的html字符串)获得,然后将它们添加到容器中,并添加到这些元素侦听器中。

DEMO: http://jsfiddle.net/3cD4G/1/

演示:http://jsfiddle.net/3cD4G/1/

HTML:

HTML:

<div id="container">

</div>

Javascript:

Javascript:

var container = document.getElementById("container");

function clicky(){
    alert("clicked");   
}
var tempContainer = document.createElement('div');
for(var i=0; i<4; i++){
    //Create your element as string.
    var strElem = "<button type='button' id='btn_" + i + "'>Click</button>";
    //Add that string to temp container (his html will be replaced, not added).
    tempContainer.innerHTML = strElem.trim();//Trim function used to prevent empty textnodes before element.
    //Get element from temp container.
    var button = tempContainer.children[0];
    //Empty tempContainer for better security (But about which security I'm talking in JavaScript in string element generation :) )
    tempContainer.innerHTML = '';

    //Add your button to container.
    container.appendChild(button);

    //Add event listener to button:
    //document.getElementById("btn_" + i).onclick = clicky;
    //Better way to add event listener:
    button.addEventListener('click', clicky);
}

DEMO: http://jsfiddle.net/3cD4G/1/

演示:http://jsfiddle.net/3cD4G/1/

#1


5  

So you're adding new elements to a container by overwriting the innerHTML or appending to it using +=. This is your problem. When you overwrite the innerHTML or append to it, you are destroying and recreating all elements within it and this causes them to lose any bound event handlers (ie your click handler).

因此,通过重写innerHTML或使用+=添加新元素到容器中。这是你的问题。当您覆盖innerHTML或附加到它时,您正在销毁并重新创建其中的所有元素,这将导致它们丢失任何绑定事件处理程序(即单击处理程序)。

This fiddle reproduces your problem. Only the last button has a click handler.

这只小提琴再现了你的问题。只有最后一个按钮有一个单击处理程序。

The solution is to build DOM elements using document.createElement() and use appendChild() or similar to append them, instead of creating/appending raw HTML. This way, your previous elements event handlers will remain intact.

解决方案是使用document.createElement()构建DOM元素,并使用appendChild()或类似于追加它们,而不是创建/追加原始HTML。这样,您以前的元素事件处理程序将保持不变。

This Fiddle uses DOM nodes instead of raw HTML and all buttons have a click handler.

这个小提琴使用DOM节点代替原始HTML,所有按钮都有一个单击处理程序。

Example fix:

例修复:

var container = document.getElementById("container");
var elem;

function clicky(){
    alert("clicked");   
}

for(var i=0; i<4; i++){
    elem = document.createElement('button');
    elem.id = "btn_" + i;
    elem.appendChild(document.createTextNode('Click'));
    elem.addEventListener("click", clicky);
    container.appendChild(elem);
}

#2


2  

I quess you do something like that

我敢说你是做那种事的

//Place where you add elements.
var container = document.body;

you create element and add listener to that element(button):

创建元素并向该元素(按钮)添加侦听器:

var button = '<button id="btn1x">Button 1</button>';
container.innerHTML += button;

//product.id = 'btn1';
document.getElementById(product.id+"x").addEventListener("click", removeItem);

and then you add in the same way new elements and add for them event listeners before next element will be generated.

然后添加相同的方法,在生成下一个元素之前添加新元素并为它们添加事件监听器。

If my quess is right, then your problem is that you replace whole content of container so previous event listens are lost.

如果我的quess是对的,那么您的问题是您替换了容器的整个内容,从而丢失了以前的事件监听。

stringVariable += 'abc' is the same as stringVariable = stringVariable + 'abc'. Because of that you overwrite html.

stringVariable += 'abc'和stringVariable = stringVariable + 'abc'是一样的。因为这样你就覆盖了html。

You should create elements from functions, not from string as you do now.

应该从函数中创建元素,而不是像现在这样从字符串中创建元素。

var button = document.createElement('button');
button.id = product.id + 'x'; 
button.innerText = 'Button 1'; // Title of button.

//Add button to container.
container.appendChild(button);

//Add event listener to created button.
button.addEventListener('click', myFunc); 

UPDATE:

更新:

There are a way to parse your string to element.

有一种方法可以将字符串解析为元素。

First create container where will be set inner html from string, then get from that temp container first element (or more elements, depends from your html string), then add them to container and add to these elements listeners.

首先创建一个容器,其中将从字符串中设置内部html,然后从temp容器的第一个元素(或更多元素,取决于您的html字符串)获得,然后将它们添加到容器中,并添加到这些元素侦听器中。

DEMO: http://jsfiddle.net/3cD4G/1/

演示:http://jsfiddle.net/3cD4G/1/

HTML:

HTML:

<div id="container">

</div>

Javascript:

Javascript:

var container = document.getElementById("container");

function clicky(){
    alert("clicked");   
}
var tempContainer = document.createElement('div');
for(var i=0; i<4; i++){
    //Create your element as string.
    var strElem = "<button type='button' id='btn_" + i + "'>Click</button>";
    //Add that string to temp container (his html will be replaced, not added).
    tempContainer.innerHTML = strElem.trim();//Trim function used to prevent empty textnodes before element.
    //Get element from temp container.
    var button = tempContainer.children[0];
    //Empty tempContainer for better security (But about which security I'm talking in JavaScript in string element generation :) )
    tempContainer.innerHTML = '';

    //Add your button to container.
    container.appendChild(button);

    //Add event listener to button:
    //document.getElementById("btn_" + i).onclick = clicky;
    //Better way to add event listener:
    button.addEventListener('click', clicky);
}

DEMO: http://jsfiddle.net/3cD4G/1/

演示:http://jsfiddle.net/3cD4G/1/