KineticJS:克隆重复类自定义事件

时间:2013-07-15 16:36:24

标签: javascript-events clone kineticjs

我在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时有不同的方法吗?

1 个答案:

答案 0 :(得分:1)

这是一种奇怪的行为..我看了一会儿却无法回答为什么clone()重复了你的事件监听器。看起来,由于您构建Kinetic.Entity的方式,每次clone()您的实体,它都会像正常一样克隆节点,但也会再次添加您定义的eventListeners(这是不受欢迎的)

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

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

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

this.off('mouseover mouseout dblclick');

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

  1. 如果您删除之前之前的节点,那么新节点仍然会有原始的eventListeners + clone()似乎添加了一组您定义的eventListeners,因此您最终会得到我们不想要的 2 个eventListeners。
  2. 如果您在删除eventListeners之后复制了节点,那么原始节点将丢失它的eventListeners,然后新节点将没有eventListeners开头,但是clone() method添加了一组eventListeners。
  3. 无论如何,我确实找到了一种方法,所以希望它适合你。我创建了一个添加事件的新方法:

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

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

    然后,对于您的双击事件,您可以通过在复制的节点上调用off来删除您的eventListeners(而不是 - 您点击的节点!) ,原始节点保持它的eventListeners,新节点删除所有复制和复制的eventListener。从复制的节点中删除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')之类的东西相比,这使事情变得更清晰,更具可扩展性并且更易于管理。试想一下,如果您添加了一个像mousedown这样的新eventListener,您还需要将off函数编辑为.off('mouseover mouseout dblclick mousedown'),并在每次添加其他事件时进行编辑!