Javascript 使用RequireJS加载Youtube Iframe API

Javascript 使用RequireJS加载Youtube Iframe API,javascript,youtube-api,requirejs,Javascript,Youtube Api,Requirejs,我试图在一个用requirejs定义的模块中使用Youtube Iframe API。由于这个API是异步加载的,并且在加载后调用函数,所以我使用了一个名为“async”的requireJS插件,该插件以前在GoogleMapsAPI中使用过 然而,这一次有些东西不起作用了。我的模块是这样开始的: define(['text!fmwk/widgets/video/video.html','fmwk/utils/browser','async!http://www.youtube.com/ifra

我试图在一个用requirejs定义的模块中使用Youtube Iframe API。由于这个API是异步加载的,并且在加载后调用函数,所以我使用了一个名为“async”的requireJS插件,该插件以前在GoogleMapsAPI中使用过

然而,这一次有些东西不起作用了。我的模块是这样开始的:
define(['text!fmwk/widgets/video/video.html','fmwk/utils/browser','async!http://www.youtube.com/iframe_api'],函数(videoTpl,根){…}

chrome控制台会触发此错误:
Uncaught错误:模块的加载超时:异步!http://www.youtube.com/iframe_api_unnormalized3,异步!http://www.youtube.com/iframe_api
http://requirejs.org/docs/errors.html#timeout

如果我不使用异步插件,那么对象YT或其函数是未定义的,如果我下载API代码,也会发生同样的情况。如果我在html文件的head标记中放置脚本标记,则有时会加载API。所有这些都是意料之中的,但我不明白,因为异步插件失败了


感谢您的关注和帮助:)

我不熟悉
async
requireJS插件,但这里有一些示例代码(取自)从名为
player
的requireJS模块中异步加载iframe API。不过,它使用jQuery进行实际的库加载

define(['jquery'], function($) {
  var player = {
    playVideo: function(container, videoId) {
      if (typeof(YT) == 'undefined' || typeof(YT.Player) == 'undefined') {
        window.onYouTubeIframeAPIReady = function() {
          player.loadPlayer(container, videoId);
        };

        $.getScript('//www.youtube.com/iframe_api');
      } else {
        player.loadPlayer(container, videoId);
      }
    },

    loadPlayer: function(container, videoId) {
      new YT.Player(container, {
        videoId: videoId,
        width: 356,
        height: 200,
        // For a list of all parameters, see:
        // https://developers.google.com/youtube/player_parameters
        playerVars: {
          autoplay: 1,
          controls: 0,
          modestbranding: 1,
          rel: 0,
          showinfo: 0
        }
      });
    }
  };

  return player;
});

另一个选项使用require加载外部javascript,并在加载javascript时发出带有上下文的jQuery承诺回调

this.initVideo = function emebdvideo(){
        //Have we already loaded the youtube iframe API?
        if(typeof YT === 'undefined' || typeof YT.Player == 'undefined'){
            var loaded = this.loadYTapi();
            loaded.done(this.embedVideo);
        }else{
            this.embedVideo();
        }

};

this.loadYTapi = function loadYTapi(){

        var dfd = $.Deferred(),
        context = this;

        //Load youtube js with require
        require(['https://www.youtube.com/iframe_api'], function(){
            window.onYouTubeIframeAPIReady = function() {

                //Resolve with context
                dfd.resolveWith(context);
            };
        });

        return dfd;
};

this.embedVideo = function embedVideo(){

        var youtubeId = 'youtube-id';
        var player = new YT.Player('player', {
          height: '390',
          width: '640',
          videoId: youtubeId,
          events: {
            'onReady': this.onPlayerReady,
            'onStateChange': this.onPlayerStateChange
          }
        });
};
配置requirejs 用法
经过一些研究并对其他答案不满意后,我通过扩展requireasync解决了这个问题,以及其他可能的问题,而没有额外的麻烦!插件,以支持命名回调,然后确保模块代码仅在API完全加载后执行

核心问题似乎是,YouTube Iframe API不允许您配置回调的名称,但规定它是“onyoutubeiframeapiredy”,我们对异步插件的小升级解决了这个问题。此解决方案仍然使用global window.YT,但不使用jQuery

require(
    ['async!//www.youtube.com/iframe_api!undefined:onYouTubeIframeAPIReady'],
    function() { 

        // this codes executes your code once YouTube Iframe API is loaded and ready
        player = new YT.Player({ ... });

    }
);
也适用于内联require调用:

define([], function () {
    // .. some of your other code here

    require(['async!//www.youtube.com/iframe_api!undefined:onYouTubeIframeAPIReady'],      function () {

        // this codes executes your code once YouTube Iframe API is loaded and ready
        player = new YT.Player({ ... });

    });
});
在我看来,这个代码比以前看到的任何代码都要干净得多。此外,在最后一刻加载API所带来的性能提升是巨大的,尤其是在与数十名玩家一起使用时。当然,API将只加载一次,并像往常一样缓存

升级!异步插件:

拉升级请求!异步插件:

升级应该是完全向后兼容的,即
为什么第一个插件参数是这个相当难看的未定义参数。欢迎您提出任何让它更漂亮、更简单的想法。

步骤1:需要不带extenson的YouTube

require.config({
...
youtube:'//www.youtube.com/iframe_api?noext',
...

})
这很好用,谢谢。虽然我不喜欢定义全局函数,但我认为这是解决google库奇怪需求的唯一方法。由于YT.Player未定义,随机失败。尝试将导出:“YT”更改为导出:“YT.Player”,但似乎没有帮助这正是我最初设置的方式,但仍然得到YT.Player随机失败,就像@zhopon一样。
require(
    ['async!//www.youtube.com/iframe_api!undefined:onYouTubeIframeAPIReady'],
    function() { 

        // this codes executes your code once YouTube Iframe API is loaded and ready
        player = new YT.Player({ ... });

    }
);
define([], function () {
    // .. some of your other code here

    require(['async!//www.youtube.com/iframe_api!undefined:onYouTubeIframeAPIReady'],      function () {

        // this codes executes your code once YouTube Iframe API is loaded and ready
        player = new YT.Player({ ... });

    });
});