Точечная функция Javascript с обработчиками событий

Вопрос

Как создать пользовательскую точечную функцию javascript, которая делает то же самое, что и следующий код в jQuery:

$(document).on("click touchstart", ".someClass", function() {
   // code goes here
});

Я хотел бы объявить это так:

$(".someClass").onClick(function () {
   // code goes here
});

Это необходимо:

  • работать с динамически создаваемыми элементами (отсюда jQuery .on() вместо .click())

  • работа с компьютерными кликами, а также сенсорными нажатиями

  • в идеале, но не обязательно, он должен быть написан на чистом javascript (без jQuery в самом прототипе, но все еще может быть доступен через jQuery)

Что я пробовал

Object.prototype.onClick = function() {
   $(document).on('click touchstart', this, arguments);
};

Но я получаю следующую ошибку в консоли Chrome:

Uncaught TypeError: ((n.event.special[g.origType] || {}).handle || g.handler).apply is not a function

Я думаю, что объявляю это неправильно, и, возможно, это также неправильный способ доступа к событиям в javascript.

почему dot? Это требование? потому что $(blah).on не против каждого элемента.

Bibberty 28.05.2019 21:10

Я бы возражал против попытки сделать что-то подобное. Сокрытие природы делегата on(event, selector, handler) как обычной привязки событий обязательно вызовет путаницу у будущих разработчиков. Обновлено: И учитывая, что если он действительно должен работать как делегат, если .someClass не существует, к чему бы вы привязались? Всегда привязываться к телу?

Taplar 28.05.2019 21:11

@Taplar Я думаю, что ему действительно нужно event delegation. jQuery скрывает, как это делается, и делает его похожим на метод привязки.

Bibberty 28.05.2019 21:14

@Bibberty - мы не знаем, чего хочет OP, кроме индивидуального способа сделать что-то очень простое с помощью стандартного JS.

Randy Casburn 28.05.2019 21:15

@RandyCasburn - "работа с динамически создаваемыми элементами (отсюда jQuery .on() вместо .click())"

Bibberty 28.05.2019 21:18

@Bibberty - и это: Как создать пользовательскую точечную функцию javascript, которая делает то же самое, что и следующий код в jQuery., поэтому OP необходимо вырезать и вставить простой JavaScript из исходного кода jQuery и использовать его. С линии 41 здесь :-)

Randy Casburn 28.05.2019 21:39

@RandyCasburn, он определенно мог скопировать jQuery. Всегда вариант.

Bibberty 28.05.2019 21:40

@Taplar на данный момент я единственный, кто занимается веб-разработкой на своем рабочем месте. Что касается будущих разработчиков: кажется, что .onClick не будет отличаться от одной из многих других функций, к которым привыкли программисты jQuery. Я рассматриваю это как вопрос ознакомления, а не путаницы, как в случае с любым новым разработчиком.

Grant Noe 28.05.2019 23:05

Спасибо, господа, что посмотрели это для меня. Мои познания в области javascript застряли внутри экосистемы jQuery, что затрудняет понимание того, какие операции мне действительно доступны. Спасибо Спасибо.

Grant Noe 28.05.2019 23:06
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
9
253
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

const getDiv = (name) => {
  if (Array.isArray(name) === false) name = [name];
  let div2 = document.createElement('div');
  name.forEach(n => div2.classList.add(n));
  div2.innerText = `${name}`;
  return div2;
};

const makeDivs = () => {
  const div = document.querySelector('#main');

  const {
    dataset: {
      count: x
    }
  } = div;

  for (let i = 0; i < x; i++) {
    div.appendChild(getDiv('div2'));
    div.appendChild(getDiv('div3'));
    div.appendChild(getDiv(['div2', 'div3']));
  }
};

document.addEventListener('click', ({
  target
}) => {
  if (target.matches('.div2')) console.info('You clicked a DIV2');

  if (target.matches('.div3')) console.info('You clicked a DIV3 !!')

  if (target.matches('button')) makeDivs();

});
div {
  border: 1px solid red;
  margin: 5px;
}
<div id='main' data-count = "10">

</div>
<button>Click Me!!!</button>

Оборачиваем это в пользовательскую функцию.

ПРИМЕЧАНИЕ. Я изменил параметр selector на массив, это позволяет вам передавать сложные селекторы, например. div.myClass li:hover

const getDiv = (name) => {
  if (Array.isArray(name) === false) name = [name];
  let div2 = document.createElement('div');
  name.forEach(n => div2.classList.add(n));
  div2.innerText = `${name}`;
  return div2;
};

const makeDivs = () => {
  const div = document.querySelector('#main');

  const {
    dataset: {
      count: x
    }
  } = div;

  for (let i = 0; i < x; i++) {
    div.appendChild(getDiv('div2'));
    div.appendChild(getDiv('div3'));
    div.appendChild(getDiv(['div2', 'div3']));
  }
};

document.on = (eventType, selector, callback) => {
  const events = eventType.split(' ');
  const selectors = (Array.isArray(selector)) ? selector : [selector];
  events.forEach(event => { document.addEventListener(event, (e) => {
      if (selectors.some(s => e.target.matches(s))) callback(e);
    });
  });
};

// Convenience method.
document.onClick = (selector, callback) => document.on('click', selector, callback);

// Simple
document.on('click', 'button', () => makeDivs());
document.on('click', '.div2', ({target}) => console.info('You clicked a DIV2'));

// Multi Event
document.on('click touchstart', '.div3', () => console.info('You clicked a DIV3'));

// Multi selectors
document.on('click', ['.div2', '.div3'], ({target}) => console.info('You clicked. !!'));

document.onClick('div', ({target}) => console.info('A Click Event!!'));
div {
  border: 1px solid red;
  margin: 5px;
}
<div id='main' data-count = "10">

</div>
<button>Click Me!!!</button>

@RandyCasburn, чье правило таково :)

Bibberty 28.05.2019 21:17

Спасибо, что сделал это для меня, @Bibberty. Два вопроса относительно: (1) Работает ли это с сенсорными нажатиями, а также с компьютерными кликами? (2) Нет ли способа форматировать как формат jQuery selector.event(function);? Это можно сделать только с помощью document.addEventListener("click", ({target}) => {function});?

Grant Noe 28.05.2019 23:00

Моей основной мотивацией было желание содержать необходимые функции в аккуратном пакете. Я использую один и тот же $(document).on("click touchstart", "element", function() {}); везде. Это прекрасно работает, но я склонен попытаться уменьшить многословие.

Grant Noe 28.05.2019 23:09

Вы также можете использовать «touchstart», и это сработает. Вы также можете ограничить слушателя элементом. Позвольте мне обновить для этого.

Bibberty 28.05.2019 23:10

Дайте мне знать, когда вы это сделаете. Я буду следить за своими уведомлениями.

Grant Noe 28.05.2019 23:13

Дайте мне знать, если это то, что вы ищете.

Bibberty 28.05.2019 23:42

Итак, вам нужен .onClick метод jQuery

jQuery.fn.extend({
  onClick: function(sel, cb) {
    return this.on('touchstart click', sel, function(evt) {
      evt.preventDefault();
      if (cb && typeof cb === 'function') cb.apply(this, arguments);
    })
  }
});



$(document).onClick('.someClass', function(ev) {
  console.info(ev.type)
});
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p class = "someClass">CLICK ME</p>

Или этот более простой вариант:

$.fn.onClick = function(sel, cb) {
  return this.on('touchstart click', sel, cb);
};

$(document).onClick('.someClass', function(ev) {
  ev.preventDefault();
  console.info(ev.type)
});

У тебя половина! Я пытался не печатать $(document) для каждого выбора и просто иметь его как $(".someClass").onClick(function(){});, но при этом учитывать $(document), чтобы выбирать динамически добавляемые элементы. Есть ли способ довести его до этой стадии? Большое спасибо, что нашли время, чтобы помочь!

Grant Noe 28.05.2019 23:12

Другие вопросы по теме