Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

youtube-api removeEventListener not working

I am able to add events fine.

addEventListener("onStateChange", "handleStateChange");

but when trying to remove the event, it does not.

removeEventListener("onStateChange", "handleStateChange");

handleStateChange is still being called whenever I pause/play the video. Has anyone run into this and have a solution? or is there a bug on the API?

like image 423
user3890000 Avatar asked Sep 17 '14 00:09

user3890000


2 Answers

I think the issue is that the player object of the YouTube API has no removeEventListener method. Keep in mind that when you call addEventListener, you are doing so as a method of the constructed youtube player object rather than using the one defined as a method of DOM elements (the YouTube API chooses to name their method the same in order to be more familiar for developers).

One suggestion which has worked for others in the past is to, when you're in a situation that might need to remove the event listener, you instead just redefine your state change callback ... something like:

handleStateChange = function() {};
like image 187
jlmcdonald Avatar answered Nov 04 '22 22:11

jlmcdonald


This was problematic enough for my application that I made a sort of event emitting proxy for the YouTube player object.

Usage (where player is your YouTube Iframe API Player instance):

const playerEventProxy = new YouTubeEventProxy(player);

function handleStateChange(e) {
  // …
}

playerEventProxy.on('stateChange', handleStateChange);
playerEventProxy.off('stateChange', handleStateChange);

Class:

/**
 * YouTubeEventProxy
 * Quick and dirty hack around broken event handling in the YouTube Iframe API.
 * Events are renamed, dropping the "on" and lower-casing the first character.
 * Methods 'on', 'off', etc. are supported, as-provided by event-emitter.
 * See also:  https://stackoverflow.com/q/25880573/362536
 * 
 * Brad Isbell <[email protected]>
 * License: MIT <https://opensource.org/licenses/MIT>
 */

import EventEmitter from 'event-emitter';

// From: https://developers.google.com/youtube/iframe_api_reference#Events
const ytApiEvents = [
  'onApiChange',
  'onError',
  'onPlaybackQualityChange',
  'onPlaybackRateChange',
  'onReady',
  'onStateChange'
];

export default class YouTubeEventProxy extends EventEmitter {
  constructor(player) {
    super();

    this.player = player;

    ytApiEvents.forEach((eventName) => {
      player.addEventListener(
        eventName,
        this.emit.bind(
          this,
          eventName.substr(2, 1).toLowerCase() + eventName.substr(3)
        )
      );
    });

  }
}

This is the event-emitter package: https://www.npmjs.com/package/event-emitter

like image 2
Brad Avatar answered Nov 04 '22 21:11

Brad