jquery - 为什么 .on('click', function(){}) 在附加处理程序后似乎执行该函数而没有发生任何实际点击?
问题描述
我正在尝试制作一个选择框,如果您单击活动选择,它将取消选择所有内容。但似乎选择框的更改事件在选项的单击事件之前触发。这会导致在更改事件触发期间添加的事件处理程序附件被触发,而在附加事件处理程序后实际上没有发生任何点击。解决这个问题的最佳方法是什么?
复选框单击事件在 Firefox 中的更改事件之前触发,这与 chrome 不同, 这提供了 setTimeout 作为绕过它的一种方式。但是在这种情况下,我不能这样做,因为我根本不希望更改事件触发。或者,如果有一种方法可以使第一个更改事件中的点击事件静音,那也可以,但我认为没有办法做到这一点,或者有吗?
我一直在用小提琴尝试它。我创造了
- 一个复选框来说明我想要实现的概念。
- 只有一个选项的选择框使用相同的代码来说明问题
- 一个更详细的例子,我最终想要做的不止一个选项
我用来附加处理程序的事件处理程序如下所示。有关完整代码,请参阅小提琴。
$(jqID+" option:selected").on("click", function(){
deSelect($(this).attr('id'));
});
// Checkbox test code that starts with change when first check was made, and subsequent showing click bloc code only on second click -> that is the expected behavior
$("#checkbox").on('change', function() {
console.log("changed");
$("#checkbox").on('click', function() {
console.log("clicked");
$("#checkbox").off('click');
console.log("click evthandler off");
});
console.log("click evthandler on");
});
// Select code with exact same set up
$("#selectbox").on('change', function() {
console.log("selbox changed");
$("#SO1").on('click', function() {
console.log("selopt clicked");
$("#SO1").prop("selected", false); //Added this line to deselect option
$("#SO1").off('click');
console.log("selopt click evthandler off");
});
console.log("selopt click evthandler on");
});
// Select box code: ______________________________________
// Attach the original change event handler like the above
$("#S1").on("change", function() {
toggleSelected("S1")
});
// toggleSelected baseically turns off all option level click event handlers, and then it adds it back on for only the actively selected option currently.
function toggleSelected(jsID) {
var jqID = "#" + jsID;
var selElements = $(jqID + " option:selected");
var allTargets = $(jqID);
console.log("toggleSelected Executed");
// Cleans out all event handlers on the options
allTargets.children("option").off("click");
// Attaches event handler for active option
if (typeof selElements !== "undefined" && selElements.length == 0) {
console.log("no elements selected or error reading selection set");
} else {
console.log("before attaching event handler for clicks");
$(jqID + " option:selected").on("click", function() {
console.log("within click function before deSelect");
deSelect($(this).attr('id'));
console.log("within click function after deSelect");
});
console.log("after attaching event handler for clicks");
}
}
// deSelect is deselects the option. Test functions have been removed for ease of reading
function deSelect(jsID) {
console.log("deSelect Executed");
$("#" + jsID).prop("selected", false); //This deselects the option
console.log("deSelect refresh calling of toggleSelected");
toggleSelected("S1"); //I just did S1 for the sake of simplicity here.
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="checkbox" type="checkbox">
<select id="selectbox" class="catSelect" title="Taa" size="4">
<option id="SO1" value="1" class="catOptions">Laa</option>
</select>
<select id="S1" class="catSelect" title="Taa" size="4">
<option id="SO1" value="1" class="catOptions">Laa</option>
<option id="SO2" value="2" class="catOptions">Paa</option>
<option id="SO3" value="3" class="catOptions">Waa</option>
<option id="SO4" value="4" class="catOptions">Maa</option>
</select>
如您所见,复选框按预期工作。在第一次点击时,它只显示:
- 改变了
- 点击evhandler
并且不包括
- 点击
- 单击 evhandler 关闭
当在选择框上进行选择时,控制台日志显示如下:
- SELBOX 已更改
- 选择点击 evhandler on
- 选择点击
- 选择单击 evhandler 关闭
这清楚地表明单击确实触发了,但实际上是在更改处理程序完成其工作之后。
我怎样才能使选择选项时的结果是:
- SELBOX 已更改
- 选择点击 evhandler on
第三个选择框基本相同,但有更多的测试选项。这可能会有所帮助,但如果您只需要了解我遇到的问题,您可以跳过它。但是第三个盒子的期望行为是:
- toggleSelected 已执行
- 在为点击附加事件处理程序之前
其余部分仅在随后单击所选选项时才显示:
- 在取消选择之前的点击功能内
- 取消选择已执行
- deSelect 刷新调用 toggleSelected
- toggleSelected 已执行
- 未选择任何元素或错误读取选择集
- 在取消选择后的点击功能内
解决方案
推荐阅读
- wolfram-mathematica - 正确使用 Mathematica 中的关联将标签应用于向量
- reactjs - 在 React 中提交表单时使用重定向
- react-native - 如何在 react-native 中调用其他组件中的函数
- java - 为 Spring Boot 微服务设置集成测试
- excel - 以 PDF 格式搜索特定区域
- printf - sprintf没有将信息输入数据库
- jquery - 动态创建的 html 表格行上的单行选择
- swift - 来自 api 请求的对象在 ForEach 中打印,但不在 List 中
- javascript - 如何在 vue.js 的嵌套 v-for 循环中访问元素的引用索引?
- scala - 如何根据某些条件处理 Akka 流?