Я пытаюсь сделать поле выбора, где, если вы нажмете на активный выбор, он отменит все.Но кажется, что событие изменения поля выбора срабатывает до события щелчка опции.Это приводит к тому, что вложения обработчика событий, добавленные во время запуска события изменения, запускаются без каких-либо щелчков, фактически происходящих после присоединения обработчика событий.Каков наилучший способ обойти эту проблему?
событие щелчка флажка срабатывает перед событием изменения в Firefox, в отличие от Chrome , этот предложенный setTimeout как способ обойти это.Но в данном случае я не могу этого сделать, потому что я не хочу, чтобы событие change срабатывало вообще.Или, если есть способ отключить событие click из этого события первого изменения, это тоже будет хорошо, но я не думаю, что есть способ сделать это, или есть?
Я былпробую это на скрипке.Я создал
- Флажок, чтобы проиллюстрировать концепцию того, чего я пытаюсь достичь.
- Блок выбора только с одним параметром, использующимтот же код, чтобы проиллюстрировать проблему
- Более сложный пример с более чем одним вариантом, который я в конечном итоге хочу сделать
Обработчик событий Iиспользуемый для прикрепления обработчик показан ниже.Полный код см. В скрипте.
$(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>
JS Fiddle
Как видите, флажок работал должным образом.При первом щелчке показывалось только:
- изменено
- щелкните evthandler на
ине включает
- нажал
- щелкните evthandler выключено
Когда выбор был выбран наВ поле выбора журнал консоли отображается следующим образом:
- selbox изменен
- выбранный щелчок evthandler на
- selopt clicked
- selopt click evthandler off
, который ясно показывает, что клик сработал, но это было на самом деле после обработчика измененийзавершил свою работу.
Как я могу сделать так, чтобы результат при выборе опции был:
- selbox изменен
- selopt click evthandler на
Третий блок выбора по сути тот же, но с большим количеством опций для тестирования.Это может быть полезно, но вы можете пропустить это, если вам нужно только понять проблему, с которой я столкнулся.Но желаемым поведением третьего поля будет:
- toggleSelected Выполнено
- до присоединения обработчика событий для кликов
, а остальные должны отображаться только при последующем нажатии на выбранную опцию:
- в функции щелчка до отмены выбора
- Отключить Выполнено
- Отменить выбор вызова обновления toggleSelected
- toggleSelected Выполнено
- нет выбранных элементов или ошибкавыбор выбора для чтения
- в функции щелчка после отмены выбора