Событие / последовательность событий Javascript. Вопрос: почему происходит это событие? - PullRequest
1 голос
/ 20 октября 2019

Страница в моем приложении имеет несколько простых пользовательских настроек, например, «вход / выход из системы».

На странице отображаются флажки ... затем обновляются, чтобы отобразить фактические предпочтения пользователя (отмечено / не отмечено). ).

Затем я хочу добавить прослушиватель, чтобы убедиться, что я фиксирую любые изменения в этом предпочтении.

В приведенном ниже коде (в разделе «Готово», поэтому он запускается при загрузке страницы). Сначала я обновляю HTML, чтобы отобразить правильное вкл / выкл, затем создаю прослушиватель для того же элемента, чтобы фиксировать любые последующие изменения.

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

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

Помощь / руководство приветствуются.

if (arrUserData.userPrefWordLog === 1){
    $('#logMode').prop('checked', true).change(function (e) {
      console.log('ON - stop prop...2');
      e.stopPropagation();
    });
  } else {
    console.log('OFF - stop prop...1');
    $('#logMode').prop('checked', false).change(function (e) {
      console.log('OFF - stop prop...2');
      e.stopPropagation();
    });
  }

  console.log('Now set listener for CHANGE to wordPrefs...');
  // $('body').on('change', '.wordPref1', function () {
  $('#logMode').change(function () {
    console.log('Fire change to logMode...');
    updatePrefs();
  });

Ответы [ 2 ]

1 голос
/ 20 октября 2019

Вот пример того, на что я ссылался в комментариях. Это простой JS, и я предполагаю, что вы можете выяснить, как применять в jQuery, чтобы соответствовать вашему коду. В родительском контейнере есть один слушатель события изменения. На консоли будет отображаться, какой элемент был изменен и был ли он отмечен или не отмечен при отображении логического значения.

Если наличие одного прослушивателя в родительском контейнере не соответствует вашим целям, этот код все равно должен показывать, что вы не используетене нужно два прослушивателя событий изменения для одного элемента в коде, который обновляет последние сохраненные пользовательские настройки.

Надеюсь, это поможет.

Я добавил вторую версию примера, которая нетребуется метод matches или поиск в DOM для каждого отдельного флажка по классу или идентификатору. Если вы можете структурировать HTML и объект данных, который содержит предпочтения пользователей, аналогичным образом, вы можете пройти через DOM и использовать атрибут данных HTML, чтобы еще больше упростить код.

Первый пример

"use strict";

let userPref_1 = 1, 
    userPref_2 = 0,
    userPref_3 = 1;

// Restore last selected user settings.

document.querySelector('.set_1').checked = userPref_1 === 1 ? true : false;
document.querySelector('.set_2').checked = userPref_2 === 1 ? true : false;
document.querySelector('.set_3').checked = userPref_3 === 1 ? true : false;

// Add change event listener to parent container.
document.querySelector('.parSet').addEventListener( 'change', chg_evt, false );

function chg_evt(evt)
  {
    let e = evt.target;
    if ( e.matches( '.set_1' ) )
       { console.log( 'Element set_1 changed to : ' + e.checked ); }
    else if ( e.matches( '.set_2' ) )
       { console.log( 'Element set_2 changed to : ' + e.checked ); }
    else if ( e.matches( '.set_3' ) )
       { console.log( 'Element set_3 changed to : ' + e.checked ); };

    // Invoke update user preferences function here.

  } // close chg_evt
<div class="parSet">
<label><input class="set_1" type="checkbox" role="button" unchecked>Setting One</label>
<label><input class="set_2" type="checkbox" role="button" unchecked>Setting Two</label>
<label><input class="set_3" type="checkbox" role="button" unchecked>Setting Three</label>
</div>

Второй пример

let userPrefs = [ 1, 0, 1 ], 
    p = document.querySelector('.parSet'),
    C = p.children,
    c, f;

// Restore last selected user settings.
for ( c of C )
 { 
   f = c.firstElementChild;
   f.checked = userPrefs[ f.dataset.i ] === 1 ? true : false;
 };

// Add change event listener to parent container.
p.addEventListener( 'change', chg_evt, false );

function chg_evt(evt)
  {
    let e = evt.target;
    console.log( 'User preference ' + ( parseInt(e.dataset.i) + 1 ) + ' changed to : ' + e.checked );     

    // Invoke update user preferences function here updatePrefs( e.dataset.i, e.checked) if needed.

  } // close chg_evt
<div class="parSet">
<label><input data-i="0" type="checkbox" role="button" unchecked>Setting One</label>
<label><input data-i="1" type="checkbox" role="button" unchecked>Setting Two</label>
<label><input data-i="2" type="checkbox" role="button" unchecked>Setting Three</label>
</div>
0 голосов
/ 20 октября 2019

Если весь код, который вы дали, находится в функции ready, этого не должно произойти. Программа должна выполняться последовательно. Код ниже настроен в JSFiddle ниже, который покажет, что никакое дополнительное событие не запускается до регистрации события.

  $('#logMode').prop('checked', true);
  $('#logMode').prop('checked', false);


  console.log('Now set listener for CHANGE to wordPrefs...');

  $('#logMode').change(function () {
    console.log('Fire change to logMode...');
  });

https://jsfiddle.net/ashhaq12345/rbnztvx0/4/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...