Точечная функция Javascript с обработчиками событий - PullRequest
1 голос
/ 28 мая 2019

Вопрос

Как мне создать пользовательскую функцию javascript dot, которая делает то же самое, что и следующий код в 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 не является функцией

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

Ответы [ 2 ]

3 голосов
/ 28 мая 2019

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

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.log('You clicked a DIV2');

  if (target.matches('.div3')) console.log('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 param на массив, это позволяетвам передать сложные селекторы, например 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.log('You clicked a DIV2'));

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

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

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

</div>
<button>Click Me!!!</button>
1 голос
/ 28 мая 2019

Итак, вы хотите .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.log(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.log(ev.type)
});
...