【问题标题】:KineticJS: Clone Duplicates Classes Custom EventsKineticJS:克隆重复类自定义事件
【发布时间】:2013-07-15 16:36:24
【问题描述】:

我在 KineticJS 类的构造函数中创建了一些自定义事件

    this.on('mouseover', this.mouseOver);
    this.on('mouseout', this.mouseOut);
    this.on('dblclick', this.dblclick);

当我克隆这个类时,我最终会复制这些事件侦听器。

    var copy = this.clone();
    this.parent.add(copy);
    console.log(this);
    console.log(copy);

如果您深入了解我的 Entity 类上的事件侦听器,您可以看到重复。

eventListeners: Object
  dblclick: Array[2]
  mouseout: Array[2]
  mouseover: Array[2]

完整的例子在下面的jsFiddle上,双击圆圈复制一份。 http://jsfiddle.net/qQEj7/

我是否在这里错误地定义了我的事件侦听器?使用 KineticJS 时有其他方法吗?

【问题讨论】:

  • 我想指出,在设置事件侦听器之前,我确实尝试了 this.off('mouseover mouseout dblclick');,而没有更改复制。

标签: javascript dom-events clone kineticjs


【解决方案1】:

这是一种奇怪的行为。我看了一会儿,但无法回答为什么 clone() 会复制您的事件侦听器。看起来是因为您构建 Kinetic.Entity 的方式,每次您 clone() 您的实体时,它都会像平常一样克隆节点,但也可以再次添加您定义的 eventListeners(这是不希望的)。

可能发生这种情况是因为当您clone() 实体节点时,它会克隆 eventListeners,但还会调用您的 _initEntity 函数再次绑定 eventListeners??

如果您通过常规的Kinetic.Shape 致电clone(),则不会出现此问题。这告诉我,这可能与您在 Kinetic.Entity 中定义 eventListeners 的方式以及它如何与 clone() 方法一起使用有关。

在您上面的评论中,您提到您尝试过:

this.off('mouseover mouseout dblclick');

这对我有用,但它会从原始节点(您双击)中删除 eventListeners。不过,这取决于您何时调用上述行:

  1. 如果你复制了节点之前删除了eventListeners,那么新节点仍然会有原来的eventListeners + clone()似乎添加了一组你定义的eventListeners,因此你会结束增加了 2 组我们不想要的事件监听器。
  2. 如果你复制了节点删除了eventListeners,那么原来的节点会失去它的eventListeners,然后新节点将没有eventListeners开始,但是clone()方法添加一组事件监听器。

无论如何,我确实找到了一种可行的方法,因此希望它对您有用。我创建了一个新方法来添加您的事件:

_bindEvents: function() {
    this.on('mouseover.entity', this.mouseOver);
    this.on('mouseout.entity', this.mouseOut);
    this.on('dblclick.entity', this.dblclick);
},

我在你的 _initEntity 函数中调用它。

然后,对于您的双击事件,您可以通过在 已复制 节点(不是 this - 您点击的节点!)上调用 off 来删除您的 eventListeners,即原始节点保留它的 eventListeners 的方式,新节点删除所有复制和复制的 eventListeners。从复制的节点中删除 eventsListeners 后,您可以调用 _bindEvents 将事件绑定回原位:

dblclick: function () {
    var copy = this.clone();
    copy.off('.entity');
    copy._bindEvents();
    this.parent.add(copy);
    console.log(this);
    console.log(copy);
}

这是JSFiddle

提示:请注意,我将您的事件命名为 mouseover.entitymouseout.entitydblclick.entity。这是因为 KineticJS 允许您命名事件以将它们组合在一起。将这些事件命名为 .entity 可以让我通过调用 .off('.entity') 一次性删除它们。与调用 .off('mouseover mouseout dblclick') 之类的东西相比,这使事情变得更清洁、更可扩展且更易于管理。试想一下,如果您添加了一个新的 eventListener,例如 mousedown,您还必须将您的 off 函数编辑为 .off('mouseover mouseout dblclick mousedown'),并且每隔一次添加另一个事件!

【讨论】:

  • 非常感谢。这运作良好。在设置我的听众之前,我尝试进行 .off 调用,但这不起作用。执行 .off 然后重新绑定效果很好。也感谢您的提示,很高兴知道!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-16
  • 1970-01-01
  • 2012-04-08
  • 2012-01-16
  • 2018-08-28
  • 2014-01-09
相关资源
最近更新 更多