首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Hammer.js的事件委托

使用Hammer.js的事件委托
EN

Stack Overflow用户
提问于 2013-07-26 11:15:21
回答 4查看 3.1K关注 0票数 5

我将如何使用普通的JavaScript在Hammer.js中进行jQuery样式的事件委托?例如:

代码语言:javascript
复制
Hammer(document).on('tap', '.item', function () {
  console.log('tapped')
})

这是直接可能的吗?还是我必须亲自去做代表团?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-07-26 11:47:29

您只需检查传递给处理程序的事件对象的target

这是一个演示

票数 2
EN

Stack Overflow用户

发布于 2014-08-22 15:17:00

我使用以下函数测试目标是否为委托。

代码语言:javascript
复制
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过滤器,因为我经常使用它,并且使用一些更复杂的选择器。

用法:

代码语言:javascript
复制
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
   }
});

这并不适用于所有的选择器,但我想说它比André更好,因为如果您的“目标”有子元素,它仍然可以工作。

代码语言:javascript
复制
<div id="parent">
    <div class="child">
        <div class="text">Test</div>
    </div>
</div>

安德烈在这里会失败,因为target[div.text],没有你的类。

对于_getDelegate的上述用法,让我们假设是$element = $("#parent")。如果您点击了单词"Test“,event.target将是[div.text] (您点击的位置),event.currentTarget将是[div.parent] (处理程序在其中注册)。当您使用这些参数调用_getDelegate时,您将收到[div.child]并知道您应该运行处理程序代码。

对于一个纯的JS版本,您可能想要这样的东西,在这里,您循环通过家长,看看你是否击中任何东西。

代码语言:javascript
复制
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”。此外,我的代码假设您的所有子元素都位于其父元素中。

票数 3
EN

Stack Overflow用户

发布于 2015-04-07 17:36:14

受朱尔斯回答的启发,这里是我想出的。我没有费心使用纯JS解决方案--实际上,这是为了用于Backbone.View,但很容易适应其他情况。

当节点树到达视图的根元素(this.el)时,它将停止爬升。从HammerJS事件标识的目标开始,它将查找与指定选择器匹配的第一个元素,如果找不到这样的元素,则返回undefined

要在非主干环境中使用,只需将对限制/包含元素的引用作为第三个参数(如Jools的解决方案),并使用它替换this.el

代码语言:javascript
复制
/**
 * @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;
  }

如果您有一个onTap回调函数,它可能如下所示:

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

为了把这一切联系起来,你会想要这样的东西.

代码语言:javascript
复制
this._hammer = new Hammer(this.el);
this._hammer.on('tap', _.bind(this.onTap, this));

(当您的视图被破坏时,不要忘记调用this._hammer.destroy()!)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17879906

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档