Javascript只有最后一个事件监听器工作

时间:2014-04-11 13:05:52

标签: javascript html addeventlistener

我很难向您展示我的代码,因为它遍布整个地方,但我想要做的是:

我在使用.innerHTML的函数购买中将html代码注入到DOM中,我希望将click事件添加到正在此步骤中注入的图标,因为此时我知道它的id 。所以在我注射之后我写道:

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

上面创建了

product.id,此元素是一个“X”按钮,单击该按钮将从屏幕上删除。

问题是,此代码运行多次,因为屏幕上显示的项目很多。完成后,按下“X”按钮时,只有最后一次发射。

有什么建议吗?

编辑:

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

这是我的代码:

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 个答案:

答案 0 :(得分:6)

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

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

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

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

示例修复:

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);
}

答案 1 :(得分:2)

我想你做那样的事情

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

您创建元素并向该元素添加侦听器(button):

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

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

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

如果我的问题是正确的,那么您的问题是您替换container的全部内容,以便之前的事件侦听丢失。

stringVariable += 'abc'stringVariable = stringVariable + 'abc'相同。因此你覆盖了html。

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

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); 

<强>更新

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

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

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

HTML:

<div id="container">

</div>

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/