Добавление нескольких прослушивателей событий к одному элементу
Итак, моя дилемма заключается в том, что я не хочу писать один и тот же код дважды. Один раз для события click и другого для события touchstart
.
Вот исходный код:
document.getElementById('first').addEventListener('touchstart', function(event) {
do_something();
});
document.getElementById('first').addEventListener('click', function(event) {
do_something();
});
Как я могу сжать это? Там должен быть более простой способ!
Ответы
Ответ 1
Возможно, вы можете использовать вспомогательную функцию следующим образом:
// events and args should be of type Array
function addMultipleListeners(element,events,handler,useCapture,args){
if (!(events instanceof Array)){
throw 'addMultipleListeners: '+
'please supply an array of eventstrings '+
'(like ["click","mouseover"])';
}
//create a wrapper to be able to use additional arguments
var handlerFn = function(e){
handler.apply(this, args && args instanceof Array ? args : []);
}
for (var i=0;i<events.length;i+=1){
element.addEventListener(events[i],handlerFn,useCapture);
}
}
function handler(e) {
// do things
};
// usage
addMultipleListeners(
document.getElementById('first'),
['touchstart','click'],
handler,
false);
Ответ 2
Я знаю, что это старый вопрос, но я подумал, что некоторые могут найти такой подход полезным; это может быть применено к любому подобному повторяющемуся коду:
ES6
['click','ontouchstart'].forEach( evt =>
element.addEventListener(evt, dosomething, false)
);
ES5
['click','ontouchstart'].forEach( function(evt) {
element.addEventListener(evt, dosomething, false);
});
Ответ 3
Вы можете просто определить функцию и передать ее. Анонимные функции не являются особыми, все функции могут передаваться как значения.
var elem = document.getElementById('first');
elem.addEventListener('touchstart', handler, false);
elem.addEventListener('click', handler, false);
function handler(event) {
do_something();
}
Ответ 4
Для большого количества событий это может помочь:
var element = document.getElementById("myId");
var myEvents = "click touchstart touchend".split(" ");
var handler = function (e) {
do something
};
for (var i=0, len = myEvents.length; i < len; i++) {
element.addEventListener(myEvents[i], handler, false);
}
Обновление 06/2017:
Теперь, когда новые языковые функции стали более доступными, вы можете упростить добавление ограниченного списка событий, которые используют один слушатель.
const element = document.querySelector("#myId");
function handleEvent(e) {
// do something
}
// I prefer string.split because it makes editing the event list slightly easier
"click touchstart touchend touchmove".split(" ")
.map(name => element.addEventListener(name, handleEvent, false));
Если вы хотите обрабатывать множество событий и предъявлять разные требования к слушателю, вы также можете передать объект, который большинство людей склонно забыть.
const el = document.querySelector("#myId");
const eventHandler = {
// called for each event on this element
handleEvent(evt) {
switch (evt.type) {
case "click":
case "touchstart":
// click and touchstart share click handler
this.handleClick(e);
break;
case "touchend":
this.handleTouchend(e);
break;
default:
this.handleDefault(e);
}
},
handleClick(e) {
// do something
},
handleTouchend(e) {
// do something different
},
handleDefault(e) {
console.log("unhandled event: %s", e.type);
}
}
el.addEventListener(eventHandler);
Обновление 05/2019:
const el = document.querySelector("#myId");
const eventHandler = {
handlers: {
click(e) {
// do something
},
touchend(e) {
// do something different
},
default(e) {
console.log("unhandled event: %s", e.type);
}
},
// called for each event on this element
handleEvent(evt) {
switch (evt.type) {
case "click":
case "touchstart":
// click and touchstart share click handler
this.handlers.click(e);
break;
case "touchend":
this.handlers.touchend(e);
break;
default:
this.handlers.default(e);
}
}
}
Object.keys(eventHandler.handlers)
.map(eventName => el.addEventListener(eventName, eventHandler))
Ответ 5
Если ваша функция do_something
действительно что-то делает с любыми заданными аргументами, вы можете просто передать ее как обработчик события.
var first = document.getElementById('first');
first.addEventListener('touchstart', do_something, false);
first.addEventListener('click', do_something, false);
Ответ 6
Самым простым решением для меня было передать код в отдельную функцию, а затем вызвать эту функцию в прослушивателе событий, работает как чудо.
function somefunction() { ..code goes here ..}
variable.addEventListener('keyup', function() {
somefunction(); // calling function on keyup event
})
variable.addEventListener('keydown', function() {
somefunction(); //calling function on keydown event
})
Ответ 7
У меня есть небольшое решение, которое прикрепляется к прототипу
EventTarget.prototype.addEventListeners = function(type, listener, options,extra) {
let arr = type;
if(typeof type == 'string'){
let sp = type.split(/[\s,;]+/);
arr = sp;
}
for(let a of arr){
this.addEventListener(a,listener,options,extra);
}
};
Позволяет вам дать ему строку или массив. Строка может быть разделена пробелом (''), запятой (',') ИЛИ точкой с запятой (';')
Ответ 8
document.getElementById('first').addEventListener('touchstart',myFunction);
document.getElementById('first').addEventListener('click',myFunction);
function myFunction(e){
e.preventDefault();e.stopPropagation()
do_something();
}
Ответ 9
Я только что сделал эту функцию (намеренно уменьшенной):
((i,e,f)=>e.forEach(o=>i.addEventListener(o,f)))(element, events, handler)
Использование:
((i,e,f)=>e.forEach(o=>i.addEventListener(o,f)))(element, ['click', 'touchstart'], (event) => {
// function body
});
Разница по сравнению с другими подходами заключается в том, что функция обработки определяется только один раз, а затем передается каждому addEventListener
.
РЕДАКТИРОВАТЬ:
Добавление не минимизированной версии, чтобы сделать ее более понятной. Минимизированная версия предназначалась только для копирования и использования.
((element, event_names, handler) => {
event_names.forEach( (event_name) => {
element.addEventListener(event_name, handler)
})
})(element, ['click', 'touchstart'], (event) => {
// function body
});
Ответ 10
Полусвязанный, но он предназначен для инициализации одного уникального прослушивателя событий для каждого элемента.
Вы можете использовать ползунок, чтобы показать значения в реальном времени, или проверить консоль. В элементе <input>
меня есть тег attr
называемый data-whatever
, поэтому вы можете настроить эти данные, если хотите.
sliders = document.querySelectorAll("input");
sliders.forEach(item=> {
item.addEventListener('input', (e) => {
console.log('${item.getAttribute("data-whatever")} is this value: ${e.target.value}');
item.nextElementSibling.textContent = e.target.value;
});
})
.wrapper {
display: flex;
}
span {
padding-right: 30px;
margin-left: 5px;
}
* {
font-size: 12px
}
<div class="wrapper">
<input type="range" min="1" data-whatever="size" max="800" value="50" id="sliderSize">
<em>50</em>
<span>Size</span>
<br>
<input type="range" min="1" data-whatever="OriginY" max="800" value="50" id="sliderOriginY">
<em>50</em>
<span>OriginY</span>
<br>
<input type="range" min="1" data-whatever="OriginX" max="800" value="50" id="sliderOriginX">
<em>50</em>
<span>OriginX</span>
</div>
Ответ 11
Итак, после погони за моим рассказом в течение целого дня, в конце концов, появился свет
Спасибо за все комментарии, я хотел бы, чтобы я видел их раньше, но это то, что есть. В мобильном IOS нет такого понятия, как "щелчок" в качестве прослушивателя событий, однако "коснулся" в списке элементов:
https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html#//apple_ref/doc/uid/TP40006511-SW8
Таким образом, я проверил это и имел небольшой праздник, поскольку это работало !!!!! сейчас я только что продублировал код, чтобы он работал, но позже мне придется его переписать. Затем стиль кнопки будет смотреть на это немного позже.
document.addEventListener("touchend", function(e) {
if (e.target.id === "burger-time"){
document.querySelector('nav').classList.add('open');
document.getElementById('burger-time').style.visibility ='hidden';
} else {
document.querySelector('nav').classList.remove('open');
document.getElementById('burger-time').style.visibility ='visible';
}
});
Ответ 12
Это мое решение, в котором я имею дело с несколькими событиями в моем рабочем процессе.
let h2 = document.querySelector("h2");
function addMultipleEvents(eventsArray, targetElem, handler) {
eventsArray.map(function(event) {
targetElem.addEventListener(event, handler, false);
}
);
}
let counter = 0;
function countP() {
counter++;
h2.innerHTML = counter;
}
// magic starts over here...
addMultipleEvents(['click', 'mouseleave', 'mouseenter'], h2, countP);
<h1>MULTI EVENTS DEMO - If you click, move away or enter the mouse on the number, it counts...</h1>
<h2 style="text-align:center; font: bold 3em comic; cursor: pointer">0</h2>
Ответ 13
//catch volume update
var volEvents = "change,input";
var volEventsArr = volEvents.split(",");
for(var i = 0;i<volknob.length;i++) {
for(var k=0;k<volEventsArr.length;k++) {
volknob[i].addEventListener(volEventsArr[k], function() {
var cfa = document.getElementsByClassName('watch_televised');
for (var j = 0; j<cfa.length; j++) {
cfa[j].volume = this.value / 100;
}
});
}
}
Ответ 14
Эта мини-библиотека JavaScript (1,3 КБ) может делать все эти вещи
https://github.com/Norair1997/norjs/
nor.event(["#first"], ["touchstart", "click"], [doSomething, doSomething]);