Почему .on ('click', function () {}), казалось бы, выполняла функцию без каких-либо реальных нажатий после того, как обработчик был присоединен? - PullRequest
0 голосов
/ 24 января 2019

Я пытаюсь сделать поле выбора, где, если вы нажмете на активный выбор, он отменит все.Но кажется, что событие изменения поля выбора срабатывает до события щелчка опции.Это приводит к тому, что вложения обработчика событий, добавленные во время запуска события изменения, запускаются без каких-либо щелчков, фактически происходящих после присоединения обработчика событий.Каков наилучший способ обойти эту проблему?

событие щелчка флажка срабатывает перед событием изменения в Firefox, в отличие от Chrome , этот предложенный setTimeout как способ обойти это.Но в данном случае я не могу этого сделать, потому что я не хочу, чтобы событие change срабатывало вообще.Или, если есть способ отключить событие click из этого события первого изменения, это тоже будет хорошо, но я не думаю, что есть способ сделать это, или есть?

Я былпробую это на скрипке.Я создал

  1. Флажок, чтобы проиллюстрировать концепцию того, чего я пытаюсь достичь.
  2. Блок выбора только с одним параметром, использующимтот же код, чтобы проиллюстрировать проблему
  3. Более сложный пример с более чем одним вариантом, который я в конечном итоге хочу сделать

Обработчик событий 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 Выполнено
  • нет выбранных элементов или ошибкавыбор выбора для чтения
  • в функции щелчка после отмены выбора
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...