Правильно ли я преобразовал мой Jquery слушатель событий в Javascript? Я не понимаю, как Javascript работает без указания идентификатора? - PullRequest
0 голосов
/ 26 апреля 2020

Я пытаюсь преобразовать jquery в javascript. Мое приложение представляет собой простой список дел, и я нацеливаюсь на кнопку с идентификатором # clear-complete. Всякий раз, когда я нажимаю эту кнопку в моем приложении, оно удаляет завершенные элементы задач, но я не понимаю, на что оно нацеливается, в моем новом Javascript коде.

Вот исходный Jquery код

$('#footer').on('click', '#clear-completed', this.destroyCompleted.bind(this));

Итак, я изменил его на Javascript, и этот код сработал

var footer = document.getElementById('footer');
      footer.addEventListener('click', this.destroyCompleted.bind(this))

Что я не понимаю, так это то, что произошло с идентификатором # clear-complete и как работает мой новый javascript код все еще работает, даже если я не указываю для целевой кнопки # clear-complete?

Вот код для функции destroyCompleted

destroyCompleted: function () {
            this.todos = this.getActiveTodos();
            this.filter = 'all';
            this.render();
        },

В отладчике, который он запускает через функцию activeTodos, но я нигде не вижу, на что нацелен id # clear-complete?

getActiveTodos: function () {
            return this.todos.filter(function (todo) {
                return !todo.completed;
            });
        },
        getCompletedTodos: function () {
            return this.todos.filter(function (todo) {
                return todo.completed;
            });
        },

Правильно ли я записал свой Jquery в Javascript? Или я что-то пропустил?

Кроме того, если бы у идентификатора было более одного прослушивателя событий, как бы вы правильно его кодировали? например

$('#todo-list')
                .on('change', '.toggle', this.toggle.bind(this))
                .on('dblclick', 'label', this.edit.bind(this))
                .on('keyup', '.edit', this.editKeyup.bind(this))
                .on('focusout', '.edit', this.update.bind(this))
                .on('click', '.destroy', this.destroy.bind(this));

Ответы [ 2 ]

1 голос
/ 26 апреля 2020

Эквивалент JavaScript будет:

document.querySelector('#footer').addEventListener('click', event => {
  const element = event.target.closest('#clear-completed');

  if (
    event.currentTarget !== element && 
    event.currentTarget.contains(element)
  ) {
    this.destroyCompleted(event);
  }
});

Используемая подпись $(target).on(event, selector, handler) называется делегированным обработчиком события, поэтому вызывается handler на элементе target, как вы правильно воспроизвели, но он вызывается только тогда, когда событие нацелено на элемент, соответствующий selector, который является потомком target, не включая сам target.

Соответствие селектор воспроизводится выше, проверяя, что event.currentTarget .contains() элемент, возвращаемый event.target .closest(selector).

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

document.querySelector('#footer').addEventListener('click', event => {
  const matches = selector => {
    const element = event.target.closest(selector);

    return (
      event.currentTarget !== element &&
      event.currentTarget.contains(element)
    );
  };

  if (matches('#clear-completed')) {
    this.destroyCompleted(event);
  }
});

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

function delegate (target, type, selector, handler) {
  const matches = event => {
    const element = event.target.closest(selector);

    return (
      event.currentTarget !== element &&
      event.currentTarget.contains(element)
    );
  };

  target.addEventListener(type, event => {
    if (matches(event)) {
      handler(event);
    }
  });
}

const element = document.querySelector('#todo-list');

delegate(element, 'change', '.toggle', e => this.toggle(e));
delegate(element, 'dblclick', 'label', e => this.edit(e));
delegate(element, 'keyup', '.edit', e => this.editKeyup(e));
delegate(element, 'focusout', '.edit', e => this.update(e));
delegate(element, 'click', '.destroy', e => this.destroy(e));
0 голосов
/ 26 апреля 2020

Вы настроили '# clear-complete' в функции jquery, передав аргумент '# clear-complete' своему обработчику событий on. Jquery on говорит:

https://api.jquery.com/on/ .on (события [, селектор] [, данные], обработчик)

селектор Тип: String

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

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