事件处理程序会发生什么?

时间:2014-05-21 14:27:35

标签: javascript html

示例:包含1行和1个单元格的表。 Javascript为这一个单元格和事件处理程序提供了附加新行。

<table border=1>
    <tbody id="target">
        <tr>
            <td class="hi" >I append</td>
        </tr>
    </tbody>
</table>


var els = document.getElementsByClassName("hi");
for(i=0;i<els.length;i++){
    els[i].onclick = function(){callMe(this)};
}

function callMe(t){
    var el = document.getElementById("target");
    el.innerHTML += '<tr><td class="hi" >appended...</td></tr>';
}

callMe函数被调用一次,附加一个新行,旧行保持不变(我想)。 第二次单击第一个单元格时,不会调用该函数。为什么? 那里发生了什么? 我错过了什么?

http://jsfiddle.net/2U3m3/1/

我没有使用任何库,只是普通的JavaScript。我希望第一个单元格始终可单击。它意味着永远地添加行而不仅仅是一行。

3 个答案:

答案 0 :(得分:5)

  

第二次单击第一个单元格时,不会调用该函数。为什么呢?

因为覆盖元素的innerHTML会重新重新创建所有子元素,无论你是否只是使用+=“追加”到innerHTML。

并且表单元格已被新单元替换意味着绑定到表单元格的事件处理程序也已消失。

  

callMe函数被调用一次,附加一个新行,旧行保持不变(我想)。

你在这里“假设”错了。

答案 1 :(得分:2)

如果您打算保留原始事件,则需要使用DOM方法进行行/单元格插入:

function callMe(t){
    var el = document.getElementById("target");
    var row = el.insertRow(el.rows.length);
    var cell = row.insertCell(0)
    cell.innerHTML = "Hi"
}

演示:http://jsfiddle.net/ygalanter/2U3m3/2/

答案 2 :(得分:1)

您可以直接将事件委派给班级名称。因此,具有该类的任何元素都将具有包含新创建的click事件。改编自answer here

if (document.body.addEventListener) {
    document.body.addEventListener('click',clickHandler,false);
} else {
    document.body.attachEvent('onclick',clickHandler); //for IE
}

function clickHandler(e)
{
    e = e || window.event;
    var target = e.target || e.srcElement;
    if (target.className.match(/hi/)) //or whatever classname you want
    {
        callMe(target);
    }
}