等待 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} 前缀)并查看是否解决了这个问题,但是即使它解决了,对于用户来说也不是一个有效的解决方案,因为它需要在每次访问时重新加载库。