复选框 $.change 被自身触发并循环,因为它正在 $.change 内部被修改
Posted
技术标签:
【中文标题】复选框 $.change 被自身触发并循环,因为它正在 $.change 内部被修改【英文标题】:checkbox $.change is being triggered by itself and looping because it is being modified inside $.change 【发布时间】:2017-08-24 20:49:43 【问题描述】:我有一组复选框,当您单击一个时,它们都应该被选中。
当用户单击一个复选框时,它会检查以该类名称开头的所有其他复选框。我想要的是用户点击一个复选框,$(".atpSelections").change
每次点击只触发一次。
代码如下:
$(".atpSelections").change(function()
console.log("CHANGED");
//Check ALL other checkboxes starting with that class name:
var className = $(this).attr("class");
className=className.replace("atpSelections ", "");
className=className.trim();
className=className.split("-");
//Get current checkbox state
var currentState = $(this).attr("checked");
//Now loop through all other checkboxes starting
//with the same class name and check them:
$("input[class*='"+className[0]+"-']").each(function(i)
//THIS IS TRIGGERING "$(".atpSelections").change"!!
if(currentState && currentState=="checked")
$(this).prop('checked', true);
else
$(this).prop('checked', false);
);
);
问题
问题是,当用户单击一个复选框时,$(".atpSelections").change
方法会被反复触发,因为$(this).prop('checked', true);
会再次触发$(".atpSelections").change
,而且它只是循环往复。
所以 1 单击复选框会触发 100 次“更改”事件,而我只希望它触发 一次。
如何在不再次触发$(".atpSelections").change
的情况下更改$(".atpSelections").change
内的复选框状态?
尝试
我尝试将$(".atpSelections").change
更改为$(".atpSelections").click
,但遇到了同样的问题。我认为$(this).prop('checked', true);
触发了click
事件。
解决方案
我使用了@James 的答案并改变了
var currentState = $(this).attr("checked");
到
var currentState = $(this).prop("checked") ? "checked" : "";
而且效果很好!谢谢。
这是 JSFiddle: https://jsfiddle.net/zL7amo0y/
【问题讨论】:
以编程方式更改选中的属性不会触发更改事件。你能分享html吗?到目前为止,您的代码很混乱 能否在 Question 中包含html
,创建 stacksn-ps 来演示问题?
currentState
不包含您期望的内容,请使用var currentState = $(this).prop("checked") ? "checked" : "";
【参考方案1】:
问题在于您的 currentState 变量。请在上面做一个console.log。我猜它是未定义的?
以下是您在 jQuery 和 Vanialla JS 中修复的代码。
JQuery:
$(".atpSelections").change(function()
var currentState = $(this).prop("checked");
console.log(currentState);
$("input[name='checkboxToCheck']").each(function(i)
if(currentState)
$(this).prop('checked', true);
else
$(this).prop('checked', false);
);
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form name="myForm">
<label for="checkbox1">Main Checkbox:</label>
<input class="atpSelections" value="checkbox1" type="checkbox" id="checkbox1" />
<label for="checkbox2">Checkbox2:</label>
<input name="checkboxToCheck" value="checkbox1" type="checkbox" id="checkbox1" />
<label for="checkbox3">Checkbox3:</label>
<input name="checkboxToCheck" value="checkbox1" type="checkbox" id="checkbox1" />
</form>
原版JS:
var checkbox = document.getElementById("checkbox1")
var checkboxToCheck = document.getElementsByName("checkboxToCheck");
checkboxToCheck = [].slice.call(checkboxToCheck);
function checkAllBoxes()
checkboxToCheck.forEach((element) =>
if (checkbox.checked)
element.checked = true;
else
element.checked = false;
);
checkbox.addEventListener("change", checkAllBoxes);
<form name="myForm">
<label for="checkbox1">Main Checkbox:</label>
<input value="checkbox1" type="checkbox" id="checkbox1" />
<label for="checkbox2">Checkbox2:</label>
<input name="checkboxToCheck" value="checkbox1" type="checkbox" id="checkbox1" />
<label for="checkbox3">Checkbox3:</label>
<input name="checkboxToCheck" value="checkbox1" type="checkbox" id="checkbox1" />
</form>
【讨论】:
【参考方案2】:我在想知道你的问题是什么,我也用复选框插件解决了这个问题。
试试这个
$(".atpSelections").on('change.custom', function(e)
console.log("CHANGED CUSTOM");
//Check ALL other checkboxes starting with that class name:
var className = $(this).attr("class");
className=className.replace("atpSelections ", "");
className=className.trim();
className=className.split("-");
//Get current checkbox state
var currentState = $(this).attr("checked");
//Now loop through all other checkboxes starting
//with the same class name and check them:
$("input[class*='"+className[0]+"-']")
.off('change.custom')
.each(function(i)
//THIS IS TRIGGERING "$(".atpSelections").change"!!
if(currentState && currentState=="checked")
$(this).prop('checked', true);
else
$(this).prop('checked', false);
);
);
通常没关系:)
【讨论】:
以上是关于复选框 $.change 被自身触发并循环,因为它正在 $.change 内部被修改的主要内容,如果未能解决你的问题,请参考以下文章
easyui combobox 用代码赋值不触发change事件,选择值会触发