Jquery clone div破坏事件

时间:2015-04-14 12:55:40

标签: javascript jquery html

我正在克隆div并更改所有子元素id's并将其附加到原始div下方。现在在div内,我有几个按钮,点击时会触发事件。这些按钮中的每一个都有一个class名称,我用它来触发与使用id相反的事件。但是,当我尝试单击克隆div中的任何按钮时,我的所有事件都没有被触发。

以下是我如何克隆我的div,更改id's并附加它:

$(function() {    
  var $section = $("#facility_section_info").clone();
  var $cloneID = 1; 
    $( ".addSection" ).click(function() { 
        var $sectionClone = $section.clone(true).find("*[id]").andSelf().each(function() { $(this).attr("id", $(this).attr("id") + $cloneID); });
        $('#facility_section_info').append($sectionClone);
        $cloneID++; 
    });
});

这是div中用于触发事件的原始未克隆按钮。

<input type="button" value="+" id="addRows" class="addRows"/>

以下是克隆按钮的样子:

<input type="button" value="+" id="addRows1" class="addRows">

唯一改变的是我在id的末尾添加了1。

以下是单击此按钮时触发的事件:

$(function() {
    var $componentTB = $("#component_tb"),
        $firstTRCopy = $("#row0").clone();
        $idVal = 1;
    $(".addRows").click(function() {
        var copy = $firstTRCopy.clone();
        var newId = 'row' +$idVal;
        copy.attr('id', newId);
        $idVal += 1;
        copy.children('td').last().append("<a href=\"javascript:remove('" + newId + "')\">Remove</a>");
        $componentTB.append(copy);
    });
});

所有这个函数都是以原始形式克隆表行,并将其附加到带有添加删除链接的表的末尾。当我点击我的克隆按钮时,这个功能完全适用于我需要它而不是不触发。

为什么我的克隆按钮不会触发class名称而非id调用的任何事件?

3 个答案:

答案 0 :(得分:3)

jquery clone方法有一个参数“withDataAndEvents”,你需要传递true 像这样

var copy = $firstTRCopy.clone(true);

https://api.jquery.com/clone/

答案 1 :(得分:2)

您的事件未触发,因为在您进行克隆之前已设置处理程序。您需要使用事件委派。

而不是:

$(".addRows").click(

这样做:

$("body").on("click", ".addRows",

答案 2 :(得分:1)

最简单的答案;克隆没有破坏事件。事件未触发,因为它从未分配给新元素。当您clone元素正在创建动态元素时,您正在执行的操作。这意味着它在页面加载后添加到DOM中,此时您的事件已经被委派。

您委派活动的方式并没有错。当您拥有动态元素时,这不是最佳实践。有几种方法可以解决这个问题。

  

使用.clone() withDataAndEvents 参数。

.clone() withDataAndEvents 参数旨在通过将数据和事件复制到新元素来简化此过程,因此

var copy = $firstTRCopy.clone(true)

然而,这可能会产生一些令人讨厌的副作用。例如,众所周知,要克隆id,如果您的事件已分配给id,您仍然只会在第一个元素上获得fire

  

Event Delegation - 请参阅Understanding Event Delegation

这是一种方法,我们使用parent element甚至document root对象来附加将始终触发所有子项的事件。如:

$(document).on('click', '.addRow', function(e) {...})

由于方便,所以通常不建议您附加到document root。我第一次建议它是因为我在公开场合,这是一个快速简单的答案。附加到document root不是不安全,但如果您的网页上有很多内容,则可能会成为一个问题。请注意,事件被分配的每个元素将在触发事件时冒泡。简而言之,当您通过document将“click”附加到具有委托事件的元素时,您实际上是单击整个DOM。通常情况下,这不是一个真正的问题,为了方便阅读,我整天都在使用它。

但是,更合适的方法是寻找存在于负载的最近的元素。也就是说,动态创建。简单地说,就像这样:

    $('#parentAlreadyLoaded').on('click', '.addRow', function(e) {...})
  

注意:使用.addRow$(document)$('parent element selector')分配事件更改{{1}中的事件参数}}。 function(e) {中的e$('.addRow').click中的e相同

简短示例

$(document OR 'parent').on('click', '.addRow'
function addRow(e) {
    if (console && console['log']) console.log(e);
	var par = $('#addRows'),
		tr = $('<tr />').appendTo(par),
		tdBlue = $('<td />').appendTo(tr),
		tdRed = $('<td />').appendTo(tr),
		btnBlue = $('<button />', { 'class': 'make-blue', 'text': 'Make Blue' }).appendTo(tdBlue),
		btnRed = $('<button />', { 'class': 'make-red', 'text': 'Make Red' }).appendTo(tdRed)
}

$(function() {
	$('thead button').on('click', addRow);
	$('#addRows').on('click', '.make-blue', function(e) {
        if (console && console['log']) console.log(e);
		$(this).closest('tr').removeClass('red').addClass('blue');
	});
	$(document).on('click', '.make-red', function(e) {
        if (console && console['log']) console.log(e);
		$(this).closest('tr').removeClass('blue').addClass('red');
	});
})
table { border-collapse: collapse; margin: 0 auto; }
tr { padding: .25em .5em; text-align: center; }
th, td { border: 3px groove; }
th button { margin: .25em auto; }
td button { margin: .5em; }
.blue { background-color: #00F; }
.red { background-color: #F00; }

另外

如前所述,使用<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <table> <thead> <th colspan="2"> <button>Click Me</button> </th> </thead> <tbody id="addRows"></tbody> </table>对于可读性非常方便。例如,如果我有一个简单的页面,有20个或更少的事件而且没有一个真正重叠,那么我将用它来分配事件:

$(document).on

由于jQuery的可链接性,这是可能的。当你使用$(document) .on('event', 'selector1', function(e) { /* do Work */ }) .on('differentEvent', 'selector1', function(e) { /* do Work */ }) .on('event', 'selector2', function(e) { /* do Work */ }) .on('event', 'selector3', function(e) { /* do Work */ }) .on('differentEvent', 'selector3', function(e) { /* do Work */ }) .on('differentEvent2', 'selector3', function(e) { /* do Work */ }) 来阻止冒泡时,请小心这样做。