使用绑定的自取消事件

时间:2018-08-23 18:40:28

标签: javascript lottie bodymovin

我在这里寻找的是一种从该方法中引用绑定方法的方法,目的是从事件侦听器中删除事件侦听器。

我想创建一个方法来处理几个不同事件的相同动作。

我有一个函数可以处理称为rotateActiveItem的元素。它查看列表项列表,并一次激活一个。

在我的构造函数中,我想设置一些可能触发rotateLoadingCopy的事件。

this.oneQuarter = genericDurationEvent.bind(this, animationDuration * .25);
this.half = genericDurationEvent.bind(this, animationDuration * .5);
this.threeQuarters = genericDurationEvent.bind(this, animationDuration * .75);

每个都添加到动画的事件中:

this.animation_.addEventListener('enterFrame', this.oneQuarter);
this.animation_.addEventListener('enterFrame', this.half);
this.animation_.addEventListener('enterFrame', this.threeQuarters);

然后事件检查持续时间,执行轮换,然后将其从eventListeners中移除。

genericDurationEvent(duration, event) {
  if (event.currentTime >= duration) {
    // Activate the next loading text element.
    this.rotateActiveItem();

    // Stop listening for this event.
    this.animation_.removeEventListener('enterFrame', /*What goes here?*/);
  }
}

起初我以为我可以将绑定方法绑定到另一种方法上,但这是绑定函数的麻烦之处。

然后我以为arguments.callee可以做到这一点,但是我在严格模式下不推荐使用它。

1 个答案:

答案 0 :(得分:1)

我建议您使用一种闭合模式,并动态生成处理程序,以便您可以保留对该函数的引用。

genericDurationEvent(context, duration) {
  var handler = function (event) {
    if (event.currentTime >= duration) {
      // Activate the next loading text element.
      this.rotateActiveItem();

      // Stop listening for this event.
      this.animation_.removeEventListener('enterFrame', handler);
    }
  }.bind(context);
  return handler;
}

this.oneQuarter = genericDurationEvent(this, animationDuration * .25);
this.half = genericDurationEvent(this, animationDuration * .5);
this.threeQuarters = genericDurationEvent(this, animationDuration * .75);

如果您想加倍努力,可以通过某种方式隔离逻辑,使生成器使任何函数的行为像“一次” ala jQuery#one()

// definition
function once (what, eventName, originalHandler) {
  function onceHandler (...args) {
    what.removeEventListener(eventName, onceHandler);
    return originalHandler.apply(this, args);
  };
  what.addEventListener(eventName, onceHandler);
}

// usage
once(this.animation_, 'enterFrame', event => {
  if (event.currentTime >= animationDuration * .25) {
    // Activate the next loading text element.
    this.rotateActiveItem();
  }
});