1

What I'm looking for here is a method to refer to a bound method from within that method for the purpose of removing an eventlistener from within the event listener.

I'd like to create a single method to handle the same action over a few different events.

I've got a function that handles rotating the elements called rotateActiveItem. It looks at a list of list items and activates one at a time.

In my constructor I'd like to set up a few, potentially many, events that trigger rotateLoadingCopy.

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

Each of these are added to the animation's events:

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

And then the event checks for duration, executes the rotation, and then should remove itself from the 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?*/);
  }
}

At first I thought maybe I could bind the bound method onto another method, but that's a rabbit hole of bound functions.

Then I thought arguments.callee would do this, but I'm in strict mode it its deprecated in strict mode.

4

1 回答 1

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();
  }
});
于 2018-08-23T23:43:23.510 回答