Прив’язка слухача до кількох подій (без JQuery)?


144

Працюючи з подіями браузера, я почав включати сенсорні заходи Safari для мобільних пристроїв. Я вважаю, що addEventListeners складаються з умовними умовами. Цей проект не може використовувати JQuery.

Стандартний слухач подій:

/* option 1 */
window.addEventListener('mousemove', this.mouseMoveHandler, false);
window.addEventListener('touchmove', this.mouseMoveHandler, false);

/* option 2, only enables the required event */
var isTouchEnabled = window.Touch || false;
window.addEventListener(isTouchEnabled ? 'touchmove' : 'mousemove', this.mouseMoveHandler, false);

JQuery bindдозволяє кілька подій, наприклад:

$(window).bind('mousemove touchmove', function(e) {
    //do something;
});

Чи є спосіб поєднати двох слухачів подій, як у прикладі JQuery? колишній:

window.addEventListener('mousemove touchmove', this.mouseMoveHandler, false);

Будь-які пропозиції або поради оцінені!


@RobG, мабуть, тому, що питання полягає у тому, як повторити деякі функції jQuery. Я не впевнений, чи правильно це використовувати тег чи ні.
Майкл Мартін-Смукер

Досить справедливо, мені просто здалося, що це питання йому не потрібно. Однак виглядає трохи химерно, видалено.
RobG

Відповіді:


104

У POJS ви додаєте одночасно одного слухача. Нечасто додавати одного і того ж слухача для двох різних подій на одному елементі. Ви можете написати власну маленьку функцію для виконання завдання, наприклад:

/* Add one or more listeners to an element
** @param {DOMElement} element - DOM element to add listeners to
** @param {string} eventNames - space separated list of event names, e.g. 'click change'
** @param {Function} listener - function to attach for each event as a listener
*/
function addListenerMulti(element, eventNames, listener) {
  var events = eventNames.split(' ');
  for (var i=0, iLen=events.length; i<iLen; i++) {
    element.addEventListener(events[i], listener, false);
  }
}

addListenerMulti(window, 'mousemove touchmove', function(){…});

Сподіваємось, це показує концепцію.

Редагувати 25.02.2016

Коментар Далгарда змусив мене переглянути це. Я думаю, що додавання одного і того ж слухача для декількох подій на одному елементі частіше тепер охоплює різні типи інтерфейсів, які використовуються, і відповідь Ісаака пропонує вдале використання вбудованих методів для зменшення коду (хоч і менше коду, саме по собі , не обов'язково бонус). Розширена функціями стрілки ECMAScript 2015 дає:

function addListenerMulti(el, s, fn) {
  s.split(' ').forEach(e => el.addEventListener(e, fn, false));
}

Подібна стратегія могла б додати одного і того ж слухача до декількох елементів, але необхідність цього може бути показником для делегування подій.


4
Дякую за вирок "It is not common to add the same listener for two different events on the same element."Іноді (зеленіші) дияволи повинні почути це, щоб знати, що вони роблять це правильно :)
Іван Дерст

1
Ви не маєте на увазі "це не звичайне"?
далгард

2
@ dalgard - зараз частіше, коли сенсорні пристрої частіше зустрічаються, але лише для обмеженої кількості подій (наприклад, миші та сенсорного руху). Те, що це потрібно, показує короткозорість іменування подій після фізичних елементів, переміщення вказівника могло б бути більш доречним. Він може бути реалізований дотиком або іншим пристроєм. Перед мишами (або мишами) були колеса x / y, деякі з яких я використовував колеса для рук та ніг (Stecometer 1970-х років). Є також трекові кулі та сфери, деякі рухаються в 3d.
RobG

2
@RobG: API, з яким я маю справу, - це DOM, і так, його недоліки є легіоном :) Але це також може бути просто питання уникнення дублікату коду у схожих слухачів.
далгард

1
@ PedroFerreira - так, напевно, напевно, більше половини браузерів, які зараз використовуються, не підтримують функції стрілок, але з ними весело грати, і завжди є Babel . ;-)
RobG

119

Деякі компактні синтаксиси, які досягають бажаного результату, POJS:

   "mousemove touchmove".split(" ").forEach(function(e){
      window.addEventListener(e,mouseMoveHandler,false);
    });

154
Або безпосередньо['mousemove', 'touchmove'].forEach(...)
Дан Даскалеску

+1 І це не потребує розширення «ECMAScript 2015 arrow arrow»! ;-)
Педро Феррейра

@zuckerburg Для початку, замість жорсткого кодування масиву ви жорстко закодували струну, а потім розділили її, ви дійсно впевнені, що це саме шлях? Ви впевнені, що це найбільш читабельний спосіб написати це? ['mousemove', 'touchmove'].forEach(function(event) { window.addEventListener(event, handler);}); буде не тільки набагато читабельніше, але й буде набагато швидше, не потрібно розділяти рядок і виконувати функцію для кожного елемента в результуючому масиві.
Іхароб Аль Асімі

2
@IharobAlAsimi цей код був написаний більше 4 років тому, я знайшов пробіл у той час. Струнний розкол повинен був стосуватися використання струни в ОП
Ісаак

1
@IharobAlAsimi я не написав код. Ви сказали, що це не читається. Ясна річ, це не тому, що ми з вами здатні читати код. Це як сперечатися над граматикою. 99% всіх програмістів вміють читати код досить чудово
Цукербург

55

Прибирання відповіді Ісаака:

['mousemove', 'touchmove'].forEach(function(e) {
  window.addEventListener(e, mouseMoveHandler);
});

EDIT

Функція помічника ES6:

function addMultipleEventListener(element, events, handler) {
  events.forEach(e => element.addEventListener(e, handler))
}

1
FYI: map! =
ForEach

10

Для мене; цей код працює чудово і є найкоротшим кодом для обробки декількох подій з однаковими (вбудованими) функціями.

var eventList = ["change", "keyup", "paste", "input", "propertychange", "..."];
for(event of eventList) {
    element.addEventListener(event, function() {
        // your function body...
        console.log("you inserted things by paste or typing etc.");
    });
}

Саме те, що я шукаю. Дякую!
Елхароні

10

ES2015:

let el = document.getElementById("el");
let handler =()=> console.log("changed");
['change', 'keyup', 'cut'].forEach(event => el.addEventListener(event, handler));

Як варіант, використовуючи for...ofцикл
чувак

3

У мене є більш просте рішення для вас:

window.onload = window.onresize = (event) => {
    //Your Code Here
}

Я перевірив це, він працює чудово, з іншого боку він компактний і нехитрий, як інші приклади тут.


1
Можливе лише одне завантаження. Можливо, ви перезаписуєте старого слухача. Залежно від вашого оточення це може бути проблемою.
HolgerJeromin

1

AddEventListener візьме просту рядок, що представляє тип event.type . Отже, вам потрібно написати спеціальну функцію для повторення кількох подій.

Це обробляється в jQuery за допомогою .split (""), а потім ітерації над списком для встановлення подій для кожного події для кожного types.

    // Add elem as a property of the handle function
    // This is to prevent a memory leak with non-native events in IE.
    eventHandle.elem = elem;

    // Handle multiple events separated by a space
    // jQuery(...).bind("mouseover mouseout", fn);
    types = types.split(" ");  

    var type, i = 0, namespaces;

    while ( (type = types[ i++ ]) ) {  <-- iterates thru 1 by 1

0

Один із способів зробити це:

const troll = document.getElementById('troll');

['mousedown', 'mouseup'].forEach(type => {
	if (type === 'mousedown') {
		troll.addEventListener(type, () => console.log('Mouse is down'));
	}
        else if (type === 'mouseup') {
                troll.addEventListener(type, () => console.log('Mouse is up'));
        }
});
img {
  width: 100px;
  cursor: pointer;
}
<div id="troll">
  <img src="http://images.mmorpg.com/features/7909/images/Troll.png" alt="Troll">
</div>

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.