Как справиться с делегированием событий с приоритетами? - PullRequest
0 голосов
/ 10 мая 2019

В моем приложении есть похожий код:

let item;

$('.parent').on('click', function () {
  item = $(this).attr('item') || 0; 
});

$('.parent').on('click', '.children', this, function () {
  doSomething();
});
<div class="parent" item="50">
  <div class="children">
  </div>
</div>

<div class="parent" item="51">
  <div class="children">
  </div>
</div>

<div class="parent" item="52">
  <div class="children">
  </div>
</div>

У меня есть родительский элемент с несколькими дочерними элементами.Щелчок в любом месте родительского элемента даст мне item информацию, поэтому я смогу загружать функции в соответствии с этой переменной item при нажатии на дочерних элементах.

Моя проблема заключается в следующем: я должен делегироватьСобытие onClick для дочерних элементов к родительскому элементу, в противном случае события будут запускаться в следующем порядке:

  1. Щелкните по любому дочернему элементу
  2. Щелкните по родительскому элементу, что слишком поздно, потому что мне нужна переменная itemfirst

У меня есть функциональность, которая заменяет родительский элемент, если он активирован, так как он был динамически вставлен в DOM, я также должен делегировать событие onClick, например:

$('.grandParent').on('click', '.parent', function () {
  item = $(this).attr('item') || 0;
});

Теперь моя проблема в том, что события снова запускаются в неправильном порядке:

  1. Нажмите на любого потомка
  2. Нажмите на родителя

Какможно ли установить событие клика на родительском элементе в качестве главного приоритета?

Редактировать:

Буду более конкретным.У меня есть список сообщений на моей странице, каждый элемент .message содержит содержимое сообщения, а также некоторые функции, такие как редактирование, удаление, установка в избранное, например, и т. Д.

Как это:

<div class="message" data-item="1">
  <a class="edit">E</a>
  <a class="delete">X</a>
  <a class="favorite">Fav</a>
  <a class="like">Like</a>
  <div class="content">
    Hello world !
  </div>
</div>
<div class="message" data-item="2">
  <a class="edit">E</a>
  <a class="delete">X</a>
  <a class="favorite">Fav</a>
  <a class="like">Like</a>
  <div class="content">
    Hello world !
  </div>
</div>

Каждая из этих функциональных возможностей будет вызывать различные функции при нажатии: edit (), delete (), like () и т. Д.

Все они будут выполнять запросы AJAX, которые затем будут отправлять itemПеременная на мой сервер, чтобы узнать, какой элемент должен быть затронут этим кликом.

Чтобы избежать повторения в моих обработчиках событий, я пытаюсь получить значение атрибута data-item с одним событием, привязанным к нажатию.message элемент, опирающийся на всплывающие дочерние элементы.

1 Ответ

1 голос
/ 10 мая 2019

Получите item там, где вы действительно хотите, и избавьтесь от обработчика на parent:

$('.parent').on('click', '.children', function () {
  item = $(this).closest('.parent').attr('item');
  doSomething();
});

РЕДАКТИРОВАТЬ:

Тогда получите предмет при нажатии на прародителя:

$('.grandParent').on('click', '.children', function () {
  item = $(this).closest('.parent').attr('item');
});

РЕДАКТИРОВАТЬ # 2:

На основании обновленных требований к ОП сделайте это следующим образом:

<div class="message" data-item="1">
  <a class="action edit" data-type="edit">E</a>
  <a class="action delete" data-type="delete">X</a>
  <a class="action favorite" data-type="favorite">Fav</a>
  <a class="like">Like</a>
  <div class="content">
    Hello world !
  </div>
</div>
<div class="message" data-item="2">
  <a class="action edit" data-type="edit">E</a>
  <a class="action delete" data-type="delete">X</a>
  <a class="action favorite" data-type="favorite">Fav</a>
  <a class="like">Like</a>
  <div class="content">
    Hello world !
  </div>
</div>

$(document).on('click','.message .action',function(e) {
   const item = $(this).closest('message').attr('item');
   switch($(this).data('type')) {
     case 'edit': doEdit(item); break;
     case 'delete': doDelete(item); break;
     case 'favorite': doFavorite(item); break;
   }
});

Видите, один обработчик событий?

Это очень распространенный способ делать то, что вы делаете. В отсутствие более надежного фреймворка (например, React), тогда с помощью простого jQuery это именно так и должно быть.

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