Safely defining variables for public callback functions in javascript

Posted by djreed on Stack Overflow See other posts from Stack Overflow or by djreed
Published on 2012-06-11T03:05:16Z Indexed on 2012/06/11 4:40 UTC
Read the original article Hit count: 175

I am working with the YouTube iFrame API to embed a number of videos on a page. Documentation here: https://developers.google.com/youtube/iframe_api_reference#Requirements

In summary, you load the API asynchronously using the following snippet:

 var tag = document.createElement('script');
 tag.src = "http://www.youtube.com/player_api";
 var firstScriptTag = document.getElementsByTagName('script')[0];
 firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

Once loaded, the API fires the predefined callback function onYouTubePlayerAPIReady.

For additional context: I am defining a library file for this in Google Closure. I am providing a namespace: goog.provide('yt.video');

I then use goog.exportSymbol so that the API can find the function. That all works fine.

My challenge is that I would like to pass 2 variables to the callback function. Is there any way to do this without defining these 2 variables in the context of the window object?

goog.provide('yt.video');

goog.require('goog.dom');

yt.video = function(videos, locales) {
  this.videos = videos;
  this.captionLocales = locales;

  this.init();
};

yt.video.prototype.init = function() {
  var tag = document.createElement('script');
  tag.src = "http://www.youtube.com/player_api";
  var firstScriptTag = document.getElementsByTagName('script')[0];
  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
};

/*
 * Callback function fired when YT API is ready
 * This is exported using goog.exportSymbol in another file and
 * is being fired by the API properly.
 */
 yt.video.prototype.onPlayerReady = function(videos, locales) {
    window.console.log('this :' + this); //logs window
    window.console.log('this.videos : ' + this.videos); //logs undefined
    /*
     * Video settings from Django variable
     */
    for(i=0; i<this.videos.length; i++) {
      var playerEvents = {};
      var embedVars = {};

      var el = this.videos[i].el;
      var playerVid = this.videos[i].vid;
      var playerWidth = this.videos[i].width;
      var playerHeight = this.videos[i].height;
      var captionLocales = this.videos[i].locales;
      if(this.videos[i].playerVars)
        var embedVars = this.videos[i].playerVars;
      }
      if(this.videos[i].events) {
        var playerEvents = this.videos[i].events;
      }

      /*
       * Show captions by default
       */
      if(goog.array.indexOf(captionLocales, 'es') >= 0) {
        embedVars.cc_load_policy = 1;
      };

      new YT.Player(el, {
        height: playerHeight,
        width: playerWidth,
        videoId: playerVid,
        events: playerEvents,
        playerVars: embedVars
    });
 };

};

To intialize this, I am currently using the following within a self-executing anonymous function:

  var videos = [
    {"vid": "video_id", "el": "player-1", "width": 640, "height": 390, "locales": ["es", "fr"], "events": {"onStateChange": stateChanged}}, 
    {"vid": "video_id", "el": "player-2", "locales": ["es", "fr"], "width": 640, "height": 390}
  ];

  var locales = ['es'];

  var videoTemplate = new yt.video(videos, locales);

© Stack Overflow or respective owner

Related posts about JavaScript

Related posts about google-closure-compiler