使用cloneNode后如何维护正确的Javascript事件(true)

时间:2020-03-05 18:43:40  来源:igfitidea点击:

我有一个包含多行输入的表单元素。将每行视为我要在Web应用程序中创建的新对象的属性。而且,我希望能够在一个HTTP POST中创建多个新对象。我正在使用Javascript的内置cloneNode(true)方法来克隆每一行。问题是每个输入行还具有一个添加链接到其onclick-event的删除链接:

// prototype based
<div class="input-line">
    <input .../>
    <a href="#" onclick="$(this).up().remove();"> Remove </a>
</div>

单击克隆的输入行的删除链接时,它还会删除从同一dom对象克隆的所有输入行。在上述DOM元素上使用cloneNode(true)之后,是否可以将" this"对象重新绑定到适当的锚标记?

解决方案

回答

看起来我们正在使用jQuery?它具有一种使用事件克隆元素的方法:http://docs.jquery.com/Manipulation/clone#true

编辑:糟糕,我看到我们正在使用原型。

回答

我们可以尝试使用innerHTML方法或者混合方法进行克隆:

var newItem = $(item).cloneNode(false);
newItem.innerHTML = $(item).innerHTML;

另外:我认为cloneNode不会克隆在addEventListener中注册的事件。但是,将克隆IE的attachEvent事件。但是我可能是错的。

回答

我在IE7和FF3中对此进行了测试,并且按预期工作,但必须进行其他操作。

这是我的测试脚本:

<div id="x">
    <div class="input-line" id="y">
        <input type="text">
        <a href="#" onclick="$(this).up().remove();"> Remove </a>
    </div>
</div>

<script>

$('x').appendChild($('y').cloneNode(true));
$('x').appendChild($('y').cloneNode(true));
$('x').appendChild($('y').cloneNode(true));

</script>

回答

要调试此问题,我将包装代码

$(this).up().remove()

在函数中:

function _debugRemoveInputLine(this) {
    debugger;
    $(this).up().remove();
}

这将使我们找出$(this)返回的内容。如果确实返回多个对象(多行),那么我们肯定知道在哪里寻找-在使用cloneNode创建元素的代码中。我们是否对结果元素做任何修改(即更改id属性)?

如果遇到我们要描述的问题,我会考虑向触发元素和" line"元素添加唯一的ID。

回答

不要在每个链接上都放置处理程序(这实际上应该是一个按钮,顺便说一句)。使用事件冒泡通过一个处理程序处理所有按钮:

formObject.onclick = function(e)
{
    e=e||event; // IE sucks
    var target = e.target||e.srcElement; // and sucks again

    // target is the element that has been clicked
    if (target && target.className=='remove') 
    {
        target.parentNode.parentNode.removeChild(target.parentNode);
        return false; // stop event from bubbling elsewhere
    }
}
<div>
  <input…>
  <button type=button class=remove>Remove without JS handler!</button>
</div>

回答

第一个答案是正确的。

Pornel隐含地建议最跨浏览器和框架不可知的解决方案。

尚未对其进行测试,但是该概念将在涉及事件的这些动态情况下起作用。