我的页面上有多个切换开关。他们来自引导程序。一切正常,但是,我在javascript控制台中遇到了一个错误。还是警告我应该说。当我在页面上只有一个切换开关并单击它时,它将在控制台中打印一行,这与预期的一样。当我使用下面的脚本动态添加另一个切换开关时,当我单击最后一个添加的切换开关时,它将仅再次打印一行,但是每隔一行将打印多行。
即当我有5个切换并单击最后一个切换时,它将在控制台中打印一行。当我单击4th时,它将打印两行,依此类推。当我单击1号时,它将打印5行。
如果我从一开始就设置了多个切换开关,但没有动态添加它们,则效果很好。
有什么想法吗?
<script>
$(window).ready(function() {
$("[data-toggle='toggle']").bootstrapToggle({
on: 'On',
off: 'Off',
size: 'small'
});
$('#addRow').on('click', function(event) {
event.preventDefault();
var rowID =+ $('table tr:last').attr('id')+1;
$('#users').find('tbody').append([
"<tr class='userRow' id='"+rowID+"'>",
"<td>"+rowID+"</td>",
"<td><input type='text' class='form-control'></td>",
"<td><input type='text' class='form-control'></td>",
"<td><input type='text' class='form-control'></td>",
"<td><input type='checkbox' class='toggle-voicemail' data-toggle='toggle'></td>",
"<td><input type='checkbox' data-toggle='toggle' class='toggle-ringgroup'></td>",
"<td><input type='checkbox' data-toggle='toggle' class='toggle-ringgroup'></td>",
"<td><input type='checkbox' data-toggle='toggle' class='toggle-ringgroup'></td>",
"<td><a class='deleteRow btn btn-danger' value='"+rowID+"'>Delete</a></td>",
"</tr>"
].join(''));
$("[data-toggle='toggle']").bootstrapToggle('destroy');
$("[data-toggle='toggle']").bootstrapToggle({ size: 'small' });
$('.toggle-voicemail').on('change', function(event) {
event.preventDefault();
var id = $(this).parents('tr').attr('id');
console.log("Voicemail for userID:"+id);
});
});
$('.toggle-voicemail').on('change', function(event) {
event.preventDefault();
var id = $(this).parents('tr').attr('id');
console.log("Voicemail for userID:"+id);
});
$('#users').on('click', 'a.deleteRow', function(event) {
event.preventDefault();
//var id = $(this).find('a').attr('value');
$(this).parents('tr').remove();
});
});
</script>
HTML
<div class="box box-primary" id="usersDetails" style="">
<div class="box-header with-border">
<h3 class="box-title">Users</h3>
</div>
<div class="box-body">
<table class="table table-condensed text-center" id="users">
<thead>
<tr>
<th>ID</th>
<th width="300">Username</th>
<th>Phone</th>
<th></th>
<th>Voicemail</th>
<th width="50">RG 1</th>
<th width="50">RG 2</th>
<th width="50">RG 3</th>
<th width="100"></th>
</tr>
</thead>
<tbody>
<tr class='userRow' id='1'>
<td>1</td>
<td><input type='text' class='form-control'></td>
<td><input type='text' class='form-control'></td>
<td><input type='text' class='form-control'></td>
<td><input type='checkbox' class='toggle-voicemail' data-toggle='toggle'></td>
<td><input type='checkbox' data-toggle='toggle' class='toggle-ringgroup'></td>
<td><input type='checkbox' data-toggle='toggle' class='toggle-ringgroup'></td>
<td><input type='checkbox' data-toggle='toggle' class='toggle-ringgroup'></td>
<td></td>
</tr>
</tbody>
</table>
<input type="button" id="addRow" value="Add another user" class="btn btn-success">
</div>
</div>
您正在将此事件绑定到“添加行”功能的内部:
$('.toggle-voicemail').on('change', function(event) {
这意味着每次添加一行时,您都将向页面上每个匹配的.toggle-voicemail
元素添加另一个绑定,包括已经具有该事件绑定的元素。
而不是在添加行时重新绑定,而是在页面加载时创建一次委托绑定,以处理动态添加的元素。基本上,可以在“添加行”功能之外执行此操作:
$(document).on('change', '.toggle-voicemail', function(event) {
event.preventDefault();
var id = $(this).parents('tr').attr('id');
console.log("Voicemail for userID:"+id);
});
您多次添加事件功能。解决方案是使您的函数不匿名:
var myFunc = function(event) {
event.preventDefault();
//var id = $(this).find('a').attr('value');
$(this).parents('tr').remove();
}
然后在调用.on之前将.off调用以防止多个侦听器
$('.toggle-voicemail').off('change', myFunc);
$('.toggle-voicemail').on('change', myFunc);
这是因为每次添加新的切换时,都会将事件侦听器重新附加到所有现有的切换上,而不仅是新创建的。
您可以制作一个let
变量来存储新生成的切换,然后代替做
$('.toggle-voicemail').on('change', function(event) { ...
您可以做:
$elem.on('change', function(event) { ...
看来您的问题是您只是添加事件处理程序,而从未删除它们。因此,您只需要将事件处理程序添加到新添加的元素中,或删除所有事件处理程序(使用.off()
),然后再次添加它们。