Javascript 使用RequireJS加载Youtube Iframe API
我试图在一个用requirejs定义的模块中使用Youtube Iframe API。由于这个API是异步加载的,并且在加载后调用函数,所以我使用了一个名为“async”的requireJS插件,该插件以前在GoogleMapsAPI中使用过 然而,这一次有些东西不起作用了。我的模块是这样开始的: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
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({ ... });
});
});