JQuery없이 리스너에 여러 이벤트를 바인딩 하시겠습니까?


144

브라우저 이벤트로 작업하는 동안 모바일 장치에 Safari의 touchEvents를 통합하기 시작했습니다. 나는 addEventListener조건부와 쌓여 있음을 발견했습니다 . 이 프로젝트는 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의 기능 중 일부를 복제하는 방법을 묻는 것이기 때문일 것입니다. 태그에 적절한 사용인지 확실하지 않습니다.
Michael Martin-Smucker

공평하게, 그 질문에는 필요하지 않은 것 같습니다. 그래도 약간 울퉁불퉁 해 보이지만 삭제되었습니다.
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(){…});

잘하면 그것은 개념을 보여줍니다.

2016-02-25 수정

Dalgard의 의견은 이것을 다시 방문하게 만들었습니다. 하나의 요소에 여러 이벤트에 동일한 리스너를 추가하는 것이 현재 사용중인 다양한 인터페이스 유형을 다루는 데 더 일반적이며, 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
"일반적이지 않다"는 말이 아닙니까?
dalgard

2
@ dalgard— 터치 장치가 더 일반적이지만 제한된 수의 이벤트 (예 : mousemove 및 touchmove)에 대해서만 더 일반적입니다. 필요한 것은 물리적 항목 다음에 이름 지정 이벤트가 짧다는 것을 보여줍니다. 포인터 이동이 더 적절했을 수 있습니다. 터치 또는 다른 장치로 구현할 수 있습니다. 마우스 (또는 마우스)가 x / y 바퀴가 있기 전에, 내가 사용한 일부는 손과 발 바퀴 (1970 년대 Stecometer)를 가지고있었습니다. 트랙 볼과 구체도 있으며 일부는 3D로 움직입니다.
RobG

2
@RobG : 내가 다루고있는 API는 DOM이며, 단점은 군단입니다 :) 그러나 단순히 유사한 리스너에서 중복 코드를 피하는 문제 일 수 있습니다.
dalgard

1
@PedroFerreira-물론 현재 사용중인 브라우저의 절반 이상이 화살표 기능을 지원하지 않지만, 사용하기에 즐겁고 항상 Babel이 있습니다. ;-)
RobG

119

원하는 결과를 달성하는 몇 가지 간단한 구문 인 POJS :

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

154
또는 직접['mousemove', 'touchmove'].forEach(...)
Dan Dascalescu

+1 그리고«ECMAScript 2015 화살표 기능»확장이 필요하지 않습니다! ;-)
Pedro Ferreira

@zuckerburg 우선, 배열을 하드 코딩하는 대신 strning을 하드 코딩 한 다음 분할했습니다. 이것이 정말로 확실한 방법입니까? 이것이 이것을 읽을 수있는 가장 읽기 쉬운 방법이라고 확신하십니까? ['mousemove', 'touchmove'].forEach(function(event) { window.addEventListener(event, handler);}); 더 읽기 쉬울뿐만 아니라 문자열을 분할하지 않고 결과 배열의 각 항목에 대해 함수를 실행할 필요가 훨씬 더 빠릅니다.
Iharob Al Asimi

2
@IharobAlAsimi이 코드는 4 년 전에 작성되었습니다. 당시에는 스페이스 바를 찾았습니다. 줄을 나누는 것은 OP의 줄 사용과 관련이 있었다
Isaac

1
@IharobAlAsimi 나는 코드를 작성하지 않았다. 읽을 수 없다고하셨습니다. 분명히 당신과 나는 둘 다 코드를 읽을 수 있기 때문에 아닙니다. 이것은 문법을 논쟁하는 것과 같습니다. 모든 프로그래머의 99 %가 코드를 아주 잘 읽을 수 있습니다
zuckerburg

55

Isaac의 답변 정리 :

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

편집하다

ES6 도우미 기능 :

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

1
참고 : map! = forEach
jpoppe

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 만 가능합니다. 아마도 당신은 오래된 청취자를 덮어 쓸 것입니다. 환경에 따라 문제가 될 수 있습니다.
HolgerJeromin

1

AddEventListenerevent.type 을 나타내는 간단한 문자열을 사용합니다 . 따라서 여러 이벤트를 반복하려면 사용자 정의 함수를 작성해야합니다.

이것은 .split ( "")을 사용하여 jQuery에서 처리 한 다음 목록을 반복하여 각에 대한 이벤트 리스너를 설정합니다 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>

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.