Birden çok olayı bir dinleyiciye bağlama (JQuery olmadan)?


144

Tarayıcı olaylarıyla çalışırken Safari'nin mobil cihazlar için touchEvents'ı kullanmaya başladım. addEventListenerŞartlar ile istiflendiğini görüyorum . Bu proje JQuery kullanamaz.

Standart bir olay dinleyicisi:

/* 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 bind, aşağıdakiler gibi birden fazla etkinliğe izin verir:

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

JQuery örneğinde olduğu gibi iki olay dinleyicisini birleştirmenin bir yolu var mı? örn:

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

Herhangi bir öneri veya ipucu takdir!


@RobG muhtemelen soru jQuery işlevselliğinin bazılarını nasıl çoğaltılacağını soruyor çünkü. Bunun bir etiket için uygun bir kullanım olup olmadığından emin değilim.
Michael Martin-Smucker

Yeterince adil, bana sorunun gerekmediği anlaşılıyordu. Gerçi biraz sinsi görünüyor, silindi.
RobG

Yanıtlar:


104

POJS'de, her seferinde bir dinleyici eklersiniz. Aynı öğeye iki farklı olay için aynı dinleyiciyi eklemek yaygın değildir. İşi yapmak için kendi küçük işlevinizi yazabilirsiniz, örneğin:

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

Umarım kavramı gösterir.

Düzenle 2016-02-25

Dalgard'ın yorumu bunu tekrar ziyaret etmeme neden oldu. Tek bir öğeye birden çok olay için aynı dinleyiciyi eklemek, kullanılan çeşitli arayüz türlerini kapsamak için daha yaygındır ve Isaac'ın cevabı, kodu azaltmak için yerleşik yöntemlerin iyi bir kullanımını sunar (daha az kod olsa da, kendi başına) , mutlaka bir bonus değildir). ECMAScript 2015 ok fonksiyonları ile genişletilmiş:

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

Benzer bir strateji, aynı dinleyiciyi birden çok öğeye ekleyebilir, ancak bunun yapılması olay yetkisi için bir gösterge olabilir.


4
Cümle için teşekkür ederim "It is not common to add the same listener for two different events on the same element."Bazen (daha yeşil) geliştiricilerin bunu doğru yaptığını bilmek için bunu duymaları gerekir :)
Ivan Durst

1
"Nadir değil" demek istemiyor musun?
dalgard

2
@ dalgard — artık dokunmatik cihazların daha yaygın olduğu, ancak yalnızca sınırlı sayıda etkinlik için (fareyle üzerine gelme ve dokunma hareketi gibi) daha yaygındır. Gerekli olması, fiziksel öğelerden sonra olayların adlandırılmasının kısa görüldüğünü gösterir, işaretçi hareketi daha uygun olabilir. Dokunmatik veya başka bir cihazla uygulanabilir. Farelerden (veya farelerden) önce x / y tekerlekleri vardı, kullandığım bazılarının el ve ayak tekerlekleri vardı (1970'ler Stecometer). Ayrıca parça topları ve küreler vardır, bazıları 3d hareket eder.
RobG

2
@RobG: Karşılaştığım API DOM ve evet, eksiklikleri lejyon :) Ama aynı zamanda benzer dinleyicilerde yinelenen koddan kaçınmak da olabilir.
dalgard

1
@ PedroFerreira - evet, elbette, şu anda kullanılmakta olan tarayıcıların yarısından fazlası ok işlevlerini desteklemiyor, ancak oynamak eğlenceli ve her zaman Babil var . ;-)
RobG

119

İstenen sonucu elde eden bazı kompakt sözdizimi POJS:

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

154
Veya doğrudan['mousemove', 'touchmove'].forEach(...)
Dan Dascalescu

+1 VE «ECMAScript 2015 ok fonksiyonları» uzantısına ihtiyaç duymaz! ;-)
Pedro Ferreira

@zuckerburg Başlamak için, diziyi kodlamak yerine, strning'i kodladınız ve sonra böltünüz, bunun yolun gerçekten olduğundan emin misiniz? Bunu yazmanın en okunaklı yolu olduğundan emin misiniz? ['mousemove', 'touchmove'].forEach(function(event) { window.addEventListener(event, handler);}); sadece daha okunabilir olmakla kalmaz, aynı zamanda dizeyi bölmek ve sonuçta ortaya çıkan dizideki her öğe için bir işlevi çalıştırmak zorunda kalmamak için çok daha hızlı olur.
Iharob Al Asimi

2
@IharobAlAsimi bu kod 4 yıl önce yazılmış, o zaman boşluk çubuğumu buldum. Dize bölünmesi OP'nin bir dize kullanmasıyla
Isaac

1
@IharobAlAsimi Kodu yazmadım. Okunamaz olduğunu söyledin. Açıkçası sen ve ben kodu okuyabildiğimizden beri değil. Bu dilbilgisi üzerinde tartışmaya benzer. Tüm programcıların% 99'u kodu oldukça iyi okuyabiliyor
zuckerburg

55

Isaac'in cevabını temizleme:

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

DÜZENLE

ES6 yardımcı işlevi:

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

1
FYI: map! =
ForEach

10

Benim için; bu kod düzgün çalışır ve aynı (satır içi) işlevlere sahip birden çok olayı işlemek için en kısa koddur.

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

Tam olarak aradığım şey. Teşekkürler!
Elharony

10

ES2015:

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

Alternatif olarak for...ofdöngüyü kullanarak
ahbap

3

Sizin için daha basit bir çözümüm var:

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

Bunu test ettim, harika çalışıyor, artı tarafta buradaki diğer örnekler gibi kompakt ve karmaşık değil.


1
Sadece bir .onload mümkündür. Belki de eski bir dinleyicinin üzerine yazıyorsunuzdur. Ortamınıza bağlı olarak bu bir sorun olabilir.
HolgerJeromin

1

AddEventListener, event.type öğesini temsil eden basit bir dize alır . Bu nedenle, birden fazla olayı yinelemek için özel bir işlev yazmanız gerekir.

Bu, jQuery'de .split ("") kullanılarak ve her biri için eventListeners'ı ayarlamak üzere liste üzerinden yinelenerek işlenir 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

Bunu yapmanın bir yolu:

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>

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.