2013-07-26 2 views
5

Hammer.js에서 일반 JavaScript로 jQuery 스타일 이벤트 위임을 수행하려면 어떻게해야합니까? 예 :Hammer.js를 사용한 이벤트 위임

Hammer(document).on('tap', '.item', function() { 
    console.log('tapped') 
}) 

직접 가능한가, 아니면 위임을 직접해야합니까?

+0

검사 대상 -됩니다 ** 만 ** 당신이 .item''와 요소를 클릭하면 작동합니다. 하지만 그 안에'.item'이라는 요소가 있다면 그 내부 요소를 클릭하십시오 - 검사 대상은 도움이되지 않습니다. (다른 답변이 제공하는) 부모를 스캔 할 필요가 있습니다. - 정확히 $ .on ('tap', '.item', function() {...}'과 같이 당신이 원하는 것입니다. jquery - 문제의 코드를 사용하면, 내부 요소를'.item'에 클릭 한 경우에도 정확한 정보를 얻을 수 있습니다. –

+0

여기서 볼 수 있듯이, 타겟을 검사하면'.item'이 아닌 버튼이 표시됩니다. http://jsbin.com/hobenunale/1/edit?html,js,output - jquery가 당신에게 배제 된 요소를 표시하는 동안 –

답변

2

처리기로 전달 된 이벤트 개체의 target을 검사하기 만하면됩니다.

Here's a demo.

+0

이것은 OP가 원하는 것이 아닙니다. –

+0

@Royi, 정말요? 그는이 대답을 받아 들였습니다. . * 4 년 전 * –

+0

'Hammer (document) .on ('tap ','.item ', function() { console.log ('탭 ') })' 그리고 타겟은 도우미가 아니 었습니다 :-) –

3

다음 함수를 사용하여 대상이 대리인인지 테스트합니다.

function _getDelegate(selector, target, currentTarget) { 

    var delegate = null; 

    while (target && target != currentTarget) { 
     delegate = $(target).filter(selector)[0]; 
     if (delegate) 
     return delegate; 
     target = target.parentNode; 
    } 

    return delegate; 

} 

jquery 필터를 많이 사용하고 일부 더 복잡한 선택기로 사용하고 있습니다.

사용법 :

var delegationSelector = ".child"; 
$element.hammer() 
$element.on("tap", function handler(event){ 
    var delegate = _getDelegate(delegationSelector, event.target, event.currentTarget); 
    if(delegate){ // or if(!delegate) return; 
     // Your handler code 
    } 
}); 

이 모든 선택기 작동하지 않습니다,하지만 난 그게 당신의 "대상"자식 요소가있는 경우 여전히 작동합니다 앙드레의보다 낫다 말할 것입니다. 예 : target[div.text]이며, 클래스가 없기 때문에

<div id="parent"> 
    <div class="child"> 
     <div class="text">Test</div> 
    </div> 
</div> 

앙드레의 여기에 실패합니다.

위의 _getDelegate 사용법에 대해 '$element = $("#parent")'이라고 말하면됩니다. "Test"라는 단어를 두드리면 [div.text] (도청 한 곳)이고 event.currentTarget[div.parent] (처리기가 등록 된 곳)이됩니다. 이 매개 변수를 사용하여 _getDelegate을 호출하면 [div.child]이 수신되고 처리기 코드를 실행해야합니다.

순수 JS 버전의 경우, 당신이 부모님을 통해 당신이 무엇인가 맞았는지보고 싶을 때 이와 같은 것을 원할 것입니다.

var delegate; 
var target = e.target; // e.g. Inner div 
var currentTarget = e.currentTarget // e.g. #parent 

while(target && target != currentTarget){ 
    if(target.className.indexOf('child')!=-1){ 
     delegate = target; 
     break; 
    } 
    target = target.parentNode; 
} 

if(delegate) { 
    console.log('delegated tap received'); 
} 

여전히 많은 결함이 있습니다. 클래스는 서로의 하위 문자열이 될 수 있기 때문에 className의 전체 색인은 좋지 않습니다. "myClass"및 "myClass2". 또한, 내 코드는 모든 하위 요소가 부모 내에 배치된다고 가정합니다.

+0

좋은데, 당신의'_isDelegate' 메소드에 대한 사용 예제가 도움이 될 것입니다. 또한'_getDelegate'가 부울을 반환하지 않기 때문에 더 정확한 이름이 아니겠습니까? :) – Lambart

+0

감사합니다. hammer 's on()을 사용하여 추가 한 것이 좋지만 핸들러에서 jquery를 사용하는 예제를 추가했습니다. 함수 이름도 변경했습니다. 나는 내가 그것을 썼을 때 나는 핸들러에서 요소를 실제로 사용하지 않았기 때문에 그것이 isDelegate라고 확신한다. 요소를 원했을 때 요소를 반환하도록하는 것은 쉬운 변경 이었지만 함수 이름을 변경하는 것을 잊었습니다. – Jools

3

Jools의 답변에서 영감을 얻은 다음 여기에 나와 있습니다. 실제로 순수 -JS 솔루션을 고집하지 않았습니다. 실제로 이것은 Backbone.View과 함께 사용하기위한 것이지만 다른 상황에도 쉽게 적용 할 수 있습니다.

노드 트리가 뷰의 루트 요소 (this.el)에 도달하면 노드 트리를 등반하는 것을 멈 춥니 다. HammerJS 이벤트로 식별되는 대상에서 시작하여 지정된 선택기와 일치하는 첫 번째 요소를 검색하고 해당 요소가 없으면 undefined을 반환합니다.

백본 환경이 아닌 환경에서 사용하려면 제한/포함 요소에 대한 참조를 세 번째 인수로 전달하고 (Jools '솔루션에서와 마찬가지로) this.el을 바꾸십시오.당신이 onTap 콜백 함수가있는 경우

/** 
* @param {Node}target - the target of the received event 
* @param {String}selector - any jQuery-compatible selector 
*/ 
getEventDelegate: function (target, selector) { 
    var delegate; 
    while (target && target != this.el) { 
     delegate = $(target).filter(selector)[0]; 
     if (delegate) { 
      return delegate; 
     } 
     target = target.parentNode; 
    } 
    return undefined; 
    } 

,이 같은 것을 볼 수 있습니다 ... 당신이 뭔가를 원하는 것,

/** 
* @param {Event}ev 
*/ 
onTap: function (ev) { 
    var target = this.getEventDelegate(ev.target, "#desiredTarget"); 
    if (target) { 
     // TODO something with the target... 
    } 
} 

를 그리고 모두를 연결하는

this._hammer = new Hammer(this.el); 
this._hammer.on('tap', _.bind(this.onTap, this)); 

(보기가 파괴되면 this._hammer.destroy()에 전화하는 것을 잊지 마십시오!)

+0

이상하지만 OP는 문제를 해결하지 못하는 답을 수락했습니다. 대상이 위임 된 이벤트의 요소와 같지 않습니다. –

-1

Lambarr의 솔루션 @ 계속 - 타이프 :

private delegateBind(rootElement:Node,e, selector:string, handler: (target:any) => any) 
    { 

    let target=e.target; 
    let o = { 

     getEventDelegate: function() 
     { 
     var delegate; 

     while (target && target != rootElement) 
     { 
      delegate = jQuery(target).filter(selector)[0]; 
      if (delegate) 
      { 
      return delegate; 
      } 

      target = target.parentNode; 
     } 
     return undefined; 
     } 

    }; 

    target = o.getEventDelegate(); 
    if (target) 
    { 
     handler(target); 
    } 
    } 

사용법 :

private registerDocumentclick() 
    { 

    Hammer(this.document).on('tap', e => 
     this.delegateBind(this.document,e,'.article', (elm) => console.log(elm.classList)) 

    ); 
    }