Как создать пользовательскую точечную функцию 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.
Я бы возражал против попытки сделать что-то подобное. Сокрытие природы делегата on(event, selector, handler)
как обычной привязки событий обязательно вызовет путаницу у будущих разработчиков. Обновлено: И учитывая, что если он действительно должен работать как делегат, если .someClass
не существует, к чему бы вы привязались? Всегда привязываться к телу?
@Taplar Я думаю, что ему действительно нужно event delegation
. jQuery скрывает, как это делается, и делает его похожим на метод привязки.
@Bibberty - мы не знаем, чего хочет OP, кроме индивидуального способа сделать что-то очень простое с помощью стандартного JS.
@RandyCasburn - "работа с динамически создаваемыми элементами (отсюда jQuery .on() вместо .click())"
@Bibberty - и это: Как создать пользовательскую точечную функцию javascript, которая делает то же самое, что и следующий код в jQuery., поэтому OP необходимо вырезать и вставить простой JavaScript из исходного кода jQuery и использовать его. С линии 41 здесь :-)
@RandyCasburn, он определенно мог скопировать jQuery. Всегда вариант.
@Taplar на данный момент я единственный, кто занимается веб-разработкой на своем рабочем месте. Что касается будущих разработчиков: кажется, что .onClick
не будет отличаться от одной из многих других функций, к которым привыкли программисты jQuery. Я рассматриваю это как вопрос ознакомления, а не путаницы, как в случае с любым новым разработчиком.
Спасибо, господа, что посмотрели это для меня. Мои познания в области javascript застряли внутри экосистемы jQuery, что затрудняет понимание того, какие операции мне действительно доступны. Спасибо Спасибо.
Вы ищете Делегация мероприятия, это позволяет вам слишком динамически добавлять элементы и по-прежнему реагировать на щелчок.
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. Два вопроса относительно: (1) Работает ли это с сенсорными нажатиями, а также с компьютерными кликами? (2) Нет ли способа форматировать как формат jQuery selector.event(function);
? Это можно сделать только с помощью document.addEventListener("click", ({target}) => {function});
?
Моей основной мотивацией было желание содержать необходимые функции в аккуратном пакете. Я использую один и тот же $(document).on("click touchstart", "element", function() {});
везде. Это прекрасно работает, но я склонен попытаться уменьшить многословие.
Вы также можете использовать «touchstart», и это сработает. Вы также можете ограничить слушателя элементом. Позвольте мне обновить для этого.
Дайте мне знать, когда вы это сделаете. Я буду следить за своими уведомлениями.
Дайте мне знать, если это то, что вы ищете.
Итак, вам нужен .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)
, чтобы выбирать динамически добавляемые элементы. Есть ли способ довести его до этой стадии? Большое спасибо, что нашли время, чтобы помочь!
почему
dot
? Это требование? потому что$(blah).on
не против каждого элемента.