我正在克隆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
调用的任何事件?
答案 0 :(得分:3)
jquery clone方法有一个参数“withDataAndEvents”,你需要传递true 像这样
var copy = $firstTRCopy.clone(true);
答案 1 :(得分:2)
您的事件未触发,因为在您进行克隆之前已设置处理程序。您需要使用事件委派。
而不是:
$(".addRows").click(
这样做:
$("body").on("click", ".addRows",
答案 2 :(得分:1)
最简单的答案;克隆没有破坏事件。事件未触发,因为它从未分配给新元素。当您clone
元素正在创建动态元素时,您正在执行的操作。这意味着它在页面加载后添加到DOM中,此时您的事件已经被委派。
您委派活动的方式并没有错。当您拥有动态元素时,这不是最佳实践。有几种方法可以解决这个问题。
使用
.clone()
的 withDataAndEvents 参数。
.clone()
的 withDataAndEvents 参数旨在通过将数据和事件复制到新元素来简化此过程,因此
var copy = $firstTRCopy.clone(true)
然而,这可能会产生一些令人讨厌的副作用。例如,众所周知,要克隆id
,如果您的事件已分配给id
,您仍然只会在第一个元素上获得fire
。
这是一种方法,我们使用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 */ })
来阻止冒泡时,请小心这样做。