Mehrere Ereignisse an einen Listener binden (ohne JQuery)?


144

Während ich mit Browserereignissen arbeite, habe ich begonnen, Safari's touchEvents für mobile Geräte zu integrieren. Ich finde, dass sich addEventListeners mit Bedingungen stapeln. Dieses Projekt kann JQuery nicht verwenden.

Ein Standard-Ereignis-Listener:

/* 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's binderlaubt mehrere Ereignisse, wie zum Beispiel:

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

Gibt es eine Möglichkeit, die beiden Ereignis-Listener wie im JQuery-Beispiel zu kombinieren? Ex:

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

Anregungen oder Tipps sind willkommen!


@RobG wahrscheinlich, weil die Frage lautet, wie einige Funktionen von jQuery repliziert werden können. Ich bin mir nicht sicher, ob dies eine angemessene Verwendung für ein Tag ist oder nicht.
Michael Martin-Smucker

Fair genug, schien mir nur, dass die Frage es nicht brauchte. Sieht allerdings etwas snarky aus, gelöscht.
RobG

Antworten:


104

In POJS fügen Sie jeweils einen Listener hinzu. Es ist nicht üblich, denselben Listener für zwei verschiedene Ereignisse auf demselben Element hinzuzufügen. Sie könnten Ihre eigene kleine Funktion schreiben, um die Arbeit zu erledigen, z.

/* 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(){…});

Hoffentlich zeigt es das Konzept.

Bearbeiten 2016-02-25

Dalgards Kommentar veranlasste mich, dies noch einmal zu überdenken. Ich denke, dass das Hinzufügen des gleichen Listeners für mehrere Ereignisse zu einem Element jetzt häufiger ist, um die verschiedenen verwendeten Schnittstellentypen abzudecken, und Isaacs Antwort bietet eine gute Verwendung integrierter Methoden, um den Code zu reduzieren (obwohl weniger Code für sich ist , nicht unbedingt ein Bonus). Die mit ECMAScript 2015 erweiterten Pfeilfunktionen bieten:

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

Eine ähnliche Strategie könnte denselben Listener zu mehreren Elementen hinzufügen, aber die Notwendigkeit, dies zu tun, könnte ein Indikator für die Ereignisdelegierung sein.


4
Vielen Dank für den Satz "It is not common to add the same listener for two different events on the same element."Manchmal müssen (grünere) Entwickler dies hören, um zu wissen, dass sie es richtig machen :)
Ivan Durst

1
Meinst du nicht "es ist nicht ungewöhnlich"?
Dalgard

2
@ dalgard - Touch-Geräte sind jetzt häufiger anzutreffen, jedoch nur für eine begrenzte Anzahl von Ereignissen (z. B. Mausbewegung und Touchmove). Dass dies erforderlich ist, zeigt die Kurzsichtigkeit der Benennung von Ereignissen nach physischen Elementen. Eine Zeigerbewegung wäre möglicherweise angemessener gewesen. Es kann per Touch oder einem anderen Gerät implementiert werden. Vor Mäusen (oder Mäusen) gab es x / y-Räder, einige, die ich verwendet habe, hatten Hand- und Fußräder (Stecometer der 1970er Jahre). Es gibt auch Trackballs und Kugeln, einige bewegen sich in 3D.
RobG

2
@RobG: Die API, mit der ich es zu tun habe, ist das DOM, und ja, seine Mängel sind zahlreich :) Aber es kann auch einfach eine Frage der Vermeidung von doppeltem Code in Listenern sein, die ähnlich sind.
Dalgard

1
@ PedroFerreira - ja natürlich, wahrscheinlich unterstützt mehr als die Hälfte der derzeit verwendeten Browser keine Pfeilfunktionen, aber es macht Spaß, mit ihnen zu spielen, und es gibt immer Babel . ;-)
RobG

119

Eine kompakte Syntax, die das gewünschte Ergebnis erzielt, POJS:

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

154
Oder direkt['mousemove', 'touchmove'].forEach(...)
Dan Dascalescu

+1 UND es wird keine Erweiterung «ECMAScript 2015 Pfeilfunktionen» benötigt! ;-)
Pedro Ferreira

@zuckerburg Sind Sie sich wirklich sicher, dass dies der richtige Weg ist, anstatt das Array fest zu codieren, das Sie fest codiert und dann aufgeteilt haben? Sind Sie sicher, dass dies der am besten lesbare Weg ist, dies zu schreiben? ['mousemove', 'touchmove'].forEach(function(event) { window.addEventListener(event, handler);}); Dies wäre nicht nur viel besser lesbar, sondern auch viel schneller, wenn die Zeichenfolge nicht geteilt und dann für jedes Element im resultierenden Array eine Funktion ausgeführt werden müsste.
Iharob Al Asimi

2
@IharobAlAsimi Dieser Code wurde vor über 4 Jahren geschrieben. Ich habe meine Leertaste in dieser Zeit gefunden. Die Aufteilung der Saiten sollte sich auf die Verwendung einer Saite durch das OP beziehen
Isaac

1
@IharobAlAsimi Ich habe den Code nicht geschrieben. Sie sagten, es sei unlesbar. Natürlich nicht, weil Sie und ich beide in der Lage sind, den Code zu lesen. Das ist wie über Grammatik zu streiten. 99% aller Programmierer können den Code ganz gut lesen
zuckerburg

55

Aufräumen von Isaacs Antwort:

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

BEARBEITEN

ES6-Hilfsfunktion:

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


10

Für mich; Dieser Code funktioniert einwandfrei und ist der kürzeste Code, um mehrere Ereignisse mit denselben (Inline-) Funktionen zu behandeln.

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.");
    });
}

Genau das, wonach ich suche. Vielen Dank!
Elharony

10

ES2015:

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

Alternativ mit der for...ofSchleife
Geck

3

Ich habe eine einfachere Lösung für Sie:

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

Ich habe dies getestet und es funktioniert großartig. Auf der positiven Seite ist es kompakt und unkompliziert wie die anderen Beispiele hier.


1
Es ist nur eine .onload möglich. Vielleicht überschreiben Sie einen alten Zuhörer. Abhängig von Ihrer Umgebung kann dies ein Problem sein.
HolgerJeromin

1

AddEventListener verwendet eine einfache Zeichenfolge, die event.type darstellt . Sie müssen also eine benutzerdefinierte Funktion schreiben, um mehrere Ereignisse zu durchlaufen.

Dies wird in jQuery behandelt, indem .split ("") verwendet und dann die Liste durchlaufen wird, um die eventListeners für jede festzulegen 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

Ein Weg, wie es geht:

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>

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.