Hammer.js에서 일반 JavaScript로 jQuery 스타일 이벤트 위임을 수행하려면 어떻게해야합니까? 예 :Hammer.js를 사용한 이벤트 위임
Hammer(document).on('tap', '.item', function() {
console.log('tapped')
})
직접 가능한가, 아니면 위임을 직접해야합니까?
Hammer.js에서 일반 JavaScript로 jQuery 스타일 이벤트 위임을 수행하려면 어떻게해야합니까? 예 :Hammer.js를 사용한 이벤트 위임
Hammer(document).on('tap', '.item', function() {
console.log('tapped')
})
직접 가능한가, 아니면 위임을 직접해야합니까?
처리기로 전달 된 이벤트 개체의 target
을 검사하기 만하면됩니다.
이것은 OP가 원하는 것이 아닙니다. –
@Royi, 정말요? 그는이 대답을 받아 들였습니다. . * 4 년 전 * –
'Hammer (document) .on ('tap ','.item ', function() { console.log ('탭 ') })' 그리고 타겟은 도우미가 아니 었습니다 :-) –
다음 함수를 사용하여 대상이 대리인인지 테스트합니다.
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". 또한, 내 코드는 모든 하위 요소가 부모 내에 배치된다고 가정합니다.
좋은데, 당신의'_isDelegate' 메소드에 대한 사용 예제가 도움이 될 것입니다. 또한'_getDelegate'가 부울을 반환하지 않기 때문에 더 정확한 이름이 아니겠습니까? :) – Lambart
감사합니다. hammer 's on()을 사용하여 추가 한 것이 좋지만 핸들러에서 jquery를 사용하는 예제를 추가했습니다. 함수 이름도 변경했습니다. 나는 내가 그것을 썼을 때 나는 핸들러에서 요소를 실제로 사용하지 않았기 때문에 그것이 isDelegate라고 확신한다. 요소를 원했을 때 요소를 반환하도록하는 것은 쉬운 변경 이었지만 함수 이름을 변경하는 것을 잊었습니다. – Jools
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()
에 전화하는 것을 잊지 마십시오!)
이상하지만 OP는 문제를 해결하지 못하는 답을 수락했습니다. 대상이 위임 된 이벤트의 요소와 같지 않습니다. –
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))
);
}
검사 대상 -됩니다 ** 만 ** 당신이 .item''와 요소를 클릭하면 작동합니다. 하지만 그 안에'.item'이라는 요소가 있다면 그 내부 요소를 클릭하십시오 - 검사 대상은 도움이되지 않습니다. (다른 답변이 제공하는) 부모를 스캔 할 필요가 있습니다. - 정확히 $ .on ('tap', '.item', function() {...}'과 같이 당신이 원하는 것입니다. jquery - 문제의 코드를 사용하면, 내부 요소를'.item'에 클릭 한 경우에도 정확한 정보를 얻을 수 있습니다. –
여기서 볼 수 있듯이, 타겟을 검사하면'.item'이 아닌 버튼이 표시됩니다. http://jsbin.com/hobenunale/1/edit?html,js,output - jquery가 당신에게 배제 된 요소를 표시하는 동안 –