等待 YouTubePlayerAPI 和 JQuery 文档准备就绪
Waiting for both YouTubePlayerAPI and JQuery Document to be ready
我的代码中似乎存在竞争条件。我正在通过以下方式异步加载 youtube 播放器 api:
<script>
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
</script>
使用 coffeescript 我有:
$ ->
window.onYouTubePlayerAPIReady = () ->
#use the youtube player api
有时 onYouTubePlayerAPIReady()
方法会在 JQuery 文档就绪方法之前触发,在这种情况下,youtube 播放器代码的 none 会运行。有没有人有处理这个问题的经验或建议?
编辑: 根据 OP (@wuliwong) 的反馈(包括示例代码),以下解决方案解决了 OP 问题中最初暗示的竞争条件:
$(document).bind 'custom-ready', () ->
... custom initialization code ...
# Ensure the 'custom-ready' is called only when both the document and the
# YouTube player API are ready. As the order this will occur in is not
# guarenteed the following code caters for both scenarios.
# Cater for the document ready first scenario
$ ->
window.onYouTubePlayerAPIReady = () ->
$(document).trigger('custom-ready')
# Cater for YouTube player API ready first scenario
window.onYouTubePlayerAPIReady = () ->
$ ->
$(document).trigger('custom-ready')
我的原始答案(针对上下文):
我过去遇到过同样的问题,但设置略有不同,在我的情况下,我正在加载 //www.youtube.com/iframe_api
。
在那种情况下,我能够将专门依赖于 YouTube 播放器 API 准备就绪的代码移动到 window.onYouTubePlayerAPIReady
回调中,并在之后使用标准 <script>
包含,因为示例:
... script tags for non-youtube reliant code ...
<script src="...jquery, plugins, site js..."></script>
... youtube specific code followed by youtube api script tag...
<script>
window.onYouTubeIframeAPIReady = function () {
$('.video-gallery').Gallery();
}
</script>
<script src="//www.youtube.com/iframe_api"></script>
但是,我认为另一种选择是为就绪状态触发自定义事件,例如 (在 CoffeeScript 中):
$(document).bind 'custom-ready', () ->
... code previously in ready event callback ...
$ ->
# Check if the page includes the youtube player api (this could be
# achieved in any number of ways, here we assume a CSS class is
# applied to the page body as an indicator.
if $('body.uses-youtube-player-api').length == 0
# This page doesn't use the youtube player api so call the
# custom ready event now.
$(document).trigger('custom-ready')
# If the page does load the youtube player api trigger our custom
# ready event in the associated callback.
window.onYouTubePlayerAPIReady = () ->
$(document).trigger('custom-ready')
我没有测试过上面的例子,所以它真的只是一个建议,因为我想我以前解决问题的原始例子在很多情况下并不理想。
回想起来,我认为这个问题似乎是由浏览器缓存了 youtube 播放器 api 代码引起的。为了证明是这种情况,您可以使用随机字符串加载 api 播放器(例如,在 script
标签 src
属性前加上 ?_ignore={insert random value}
前缀)并查看是否解决了这个问题,但是即使它解决了,对于用户来说也不是一个有效的解决方案,因为它需要在每次访问时重新加载库。
我的代码中似乎存在竞争条件。我正在通过以下方式异步加载 youtube 播放器 api:
<script>
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
</script>
使用 coffeescript 我有:
$ ->
window.onYouTubePlayerAPIReady = () ->
#use the youtube player api
有时 onYouTubePlayerAPIReady()
方法会在 JQuery 文档就绪方法之前触发,在这种情况下,youtube 播放器代码的 none 会运行。有没有人有处理这个问题的经验或建议?
编辑: 根据 OP (@wuliwong) 的反馈(包括示例代码),以下解决方案解决了 OP 问题中最初暗示的竞争条件:
$(document).bind 'custom-ready', () ->
... custom initialization code ...
# Ensure the 'custom-ready' is called only when both the document and the
# YouTube player API are ready. As the order this will occur in is not
# guarenteed the following code caters for both scenarios.
# Cater for the document ready first scenario
$ ->
window.onYouTubePlayerAPIReady = () ->
$(document).trigger('custom-ready')
# Cater for YouTube player API ready first scenario
window.onYouTubePlayerAPIReady = () ->
$ ->
$(document).trigger('custom-ready')
我的原始答案(针对上下文):
我过去遇到过同样的问题,但设置略有不同,在我的情况下,我正在加载 //www.youtube.com/iframe_api
。
在那种情况下,我能够将专门依赖于 YouTube 播放器 API 准备就绪的代码移动到 window.onYouTubePlayerAPIReady
回调中,并在之后使用标准 <script>
包含,因为示例:
... script tags for non-youtube reliant code ...
<script src="...jquery, plugins, site js..."></script>
... youtube specific code followed by youtube api script tag...
<script>
window.onYouTubeIframeAPIReady = function () {
$('.video-gallery').Gallery();
}
</script>
<script src="//www.youtube.com/iframe_api"></script>
但是,我认为另一种选择是为就绪状态触发自定义事件,例如 (在 CoffeeScript 中):
$(document).bind 'custom-ready', () ->
... code previously in ready event callback ...
$ ->
# Check if the page includes the youtube player api (this could be
# achieved in any number of ways, here we assume a CSS class is
# applied to the page body as an indicator.
if $('body.uses-youtube-player-api').length == 0
# This page doesn't use the youtube player api so call the
# custom ready event now.
$(document).trigger('custom-ready')
# If the page does load the youtube player api trigger our custom
# ready event in the associated callback.
window.onYouTubePlayerAPIReady = () ->
$(document).trigger('custom-ready')
我没有测试过上面的例子,所以它真的只是一个建议,因为我想我以前解决问题的原始例子在很多情况下并不理想。
回想起来,我认为这个问题似乎是由浏览器缓存了 youtube 播放器 api 代码引起的。为了证明是这种情况,您可以使用随机字符串加载 api 播放器(例如,在 script
标签 src
属性前加上 ?_ignore={insert random value}
前缀)并查看是否解决了这个问题,但是即使它解决了,对于用户来说也不是一个有效的解决方案,因为它需要在每次访问时重新加载库。