複数のイベントをリスナー(JQueryなし)にバインドしていますか?


144

ブラウザーイベントを処理しているときに、モバイルデバイス用のSafariのtouchEventsを組み込み始めました。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の例のように2つのイベントリスナーを組み合わせる方法はありますか?例:

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

提案やヒントは大歓迎です!


@RobGはおそらく、jQueryの機能の一部を複製する方法を尋ねる質問のためです。それがタグの適切な使用かどうかはわかりません。
Michael Martin-Smucker 14

十分に公正で、質問にはそれを必要としないと私には思えました。少しぎこちないように見えますが、削除されました。
RobG 2014

回答:


104

POJSでは、一度に1つのリスナーを追加します。同じ要素の2つの異なるイベントに同じリスナーを追加することは一般的ではありません。あなたは仕事をするためにあなた自身の小さな関数を書くことができます、例えば:

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

うまくいけば、それは概念を示しています。

2016-02-25を編集

ダルガードのコメントは私にこれを再訪させた。1つの要素の複数のイベントに同じリスナーを追加することは、現在使用されているさまざまなインターフェイスタイプをカバーするために、より一般的であると思います。Isaacの答えは、組み込みメソッドを有効に使用してコードを削減します(ただし、コード自体は少ないです) 、必ずしもボーナスではありません)。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."ときどき(より環境に配慮した)開発者は、正しく機能していることを知るためにこれを聞く必要があります:)
Ivan Durst

1
「それはアンコモンではない」という意味ですか?
ダルガード2016

2
@dalgard —タッチデバイスがより一般的になるようになりましたが、限られた数のイベント(mousemoveやtouchmoveなど)に対してのみです。必要なことは、物理的なアイテムの後にイベントを命名することの近視眼を示しているため、ポインターの移動がより適切であった可能性があります。タッチまたは他のデバイスで実装できます。マウス(またはマウス)の前にx / yホイールがあり、私が使用したものには手と足のホイールがありました(1970年代のStecometer)。トラックボールと球体もあり、3Dで動くものもあります。
RobG 2016

2
@RobG:私が扱っているAPIはDOMです。そうです、その欠点は多数あります:)しかし、同様のリスナーでコードが重複しないようにすることの問題かもしれません。
ダルガード2016

1
@PedroFerreira-はい、もちろん、おそらく現在使用されているブラウザの半分以上は、矢印機能をサポートしていませんが、操作するのは楽しいし、常にBabelがあります。;-)
RobG 2016年

119

望ましい結果を実現するいくつかのコンパクトな構文POJS:

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

154
または直接['mousemove', 'touchmove'].forEach(...)
Dan Dascalescu

+1かつ«ECMAScript 2015の矢印関数»拡張機能は必要ありません。;-)
ペドロフェレイラ

@zuckerburgそもそも、strningをハードコーディングして分割した配列をハードコーディングする代わりに、これが正しい方法であると本当に確信していますか?これがこれを書く最も読みやすい方法であると確信していますか? ['mousemove', 'touchmove'].forEach(function(event) { window.addEventListener(event, handler);}); より読みやすくなるだけでなく、文字列を分割する必要がなく、結果の配列内の各項目に対して関数を実行する必要もなくなります。
Iharob Al Asimi、

2
@IharobAlAsimiこのコードは4年以上前に書かれたもので、そのときにスペースバーを見つけました。文字列分割は、OPによる文字列の使用に関連するものでした
Isaac

1
@IharobAlAsimi私はコードを書きませんでした。あなたはそれが読めないと言った。明らかにそれはあなたと私がどちらもコードを読むことができるからではありません。これは文法論争のようなものです。すべてのプログラマーの99%がコードを非常にうまく読み取ることができます
zuckerburg

55

アイザックの答えを整理する:

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

編集

ES6ヘルパー関数:

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

1
参考

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

まさに私が探しているもの。ありがとう!
Elharony

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
可能な.onloadは1つだけです。おそらく、古いリスナーを上書きします。環境によっては、これが問題になる場合があります。
HolgerJeromin、

1

AddEventListenerは、event.typeを表す単純な文字列を取ります。したがって、複数のイベントを反復処理するカスタム関数を作成する必要があります。

これは、.split( "")を使用してjQueryで処理され、リストを反復処理して、それぞれにeventListenersを設定します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

それを行う方法の1つ:

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>

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.