加载jQuery时触发事件

时间:2017-09-11 15:26:58

标签: javascript jquery

我正在合并使用YouTube iFrame API和通过设置了defer标记的脚本标记加载的jQuery。必须设置延迟标记,因为客户端具有完美的Google页面洞察力分数,并希望保持该分数。

YouTube API在完全加载并可供使用后,immediatley调用我定义onYouTubeIframeAPIReady的函数。然后,当玩家完全加载并渲染时,它将会调用onPlayerReady

我希望在这个函数中使用jQuery,但只是在onPlayerReady函数中使用jQuery就会创建一个竞争条件(希望jQuery库在onPlayerReady被调用时已经完成加载)。

在我看来,一个可行的解决方案是使用onPlayerReady函数在调用一个测试播放器和jQuery的函数之前设置一个变量。另一个函数在jQuery准备就绪时设置一个变量,并调用相同的测试函数。

我有一些可行的代码,但检查jQuery的部分对我来说似乎很麻烦,并且还引入了少量额外的不必要延迟。我想知道是否有人知道更好的方式来运行即时jQuery变得可用的东西。基本上,jQuery的回调是否可以内置到库中?

我目前的代码如下:

var ready = {
    'jquery': false,
    'youtube' false
},
testJQueryLoaded;

testJQueryLoaded = function() {
    if(typeof jQuery == 'undefined') {
        window.setTimeout(function() {
            testJQueryLoaded();
        }, 25);
        return;
    }

    ready.jquery = true;
    postLibraryLoad();
};

testJQueryLoaded();

function onYouTubeIframeAPIReady() {
    // Stuff
};

function onPlayerReady() {
    ready.youtube = true;
    postLibraryLoad();
};

function postLibraryLoad() {
    if(!ready.jquery || !ready.youtube) {
        return;
    }

    // More stuff
};

4 个答案:

答案 0 :(得分:2)

根据@KevinB的建议,您可以使用特定load元素的<script>事件

<!DOCTYPE html>
<html>

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js" defer></script>
  <script defer>
    const dojQueryStuff = (el, params) => this.jQuery(el, params).appendTo("body");
  </script>
  <script defer>
    document
    .querySelector("script[src$='3.2.1/jquery.min.js']")
    .onload = event => {
      console.log(event.target.src);

      dojQueryStuff("<div>", {
        html: "jQuery version: " + this.jQuery().jquery + " loaded"
      });
     }
  </script>
</head>

<body>
</body>

</html>

答案 1 :(得分:1)

我认为.ready()会这样做。

$(document).ready(function(){
    ready.jquery = true;
    postLibraryLoad();
});

你可能知道但是...... 1.在加载jQuery之前,这不会抛出执行错误 2.这只会在jQuery准备就绪时执行一次。

所以我认为下面这段代码有效:

var ready = {
    'jquery': false,
    'youtube': false
};

$(document).ready(function(){
    ready.jquery = true;
    postLibraryLoad();
});

function onYouTubeIframeAPIReady() {
    // Stuff
}

function onPlayerReady() {
    ready.youtube = true;
    postLibraryLoad();
}

function postLibraryLoad() {
    if(!ready.jquery || !ready.youtube) {
        return;
    }

    // More stuff
}

假设首先在其他地方触发onYouTubeIframeAPIReady(),这个代码应该在youtube准备就绪或jQuery准备好之后运行postLibraryLoad()最多两次,最后只有当两者都是// More stuff时才运行Public Sub CompactDB() dim strFrom as string dim strTo as string strFrom = "C:\Your Database Location Including File Name and Extension" strTo = "C:\Your new Database backup location File Name and Extension" DBEngine.CompactDatabase strFrom, strTo End Sub 准备好了。

编辑:格式
编辑:添加说明

答案 2 :(得分:1)

我知道这可能看起来很奇怪,但如果你担心这个小代码,那么为什么不把它添加到底部的jQuery库中。并致电onYouTubeIframeAPIReady()。您也可以完全删除此部分ready.jquery = true;

答案 3 :(得分:0)

我现在遇到了这个问题。我要处理它的方法是执行以下操作。

<script>

// Custom Event Polyfill for IE11
if ( typeof window.CustomEvent !== "function" ) {
  function CustomEvent ( event, params ) {
    params = params || { bubbles: false, cancelable: false, detail: undefined };
    var evt = document.createEvent( 'CustomEvent' );
    evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
    return evt;
  }

  CustomEvent.prototype = window.Event.prototype;

  window.CustomEvent = CustomEvent;
}

</script>

然后在我从服务器而不是通过 Google 加载 jQuery 文件的末尾添加这个

<script>

  // Start of jQuery script
  (function (global, factory) {
    // jquery stuff in here
  })( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
    // ALL OF THE jquery CODE IN HERE ....
    return jQuery;
  });

  // I Add this at the end.

  var jQueryLoadedEvent = new CustomEvent('jQueryLoaded');
  document.dispatchEvent(jQueryLoadedEvent);

</script>

然后我会用这个包装我自己的脚本。

<script>
  
  document.addEventListener('jQueryLoaded', function (e) {
    (function ($) {

      console.log('All of my code in here. Or some of it, I can wrap more code with the same event listener elsewhere.');
      console.log('jQuery version: ', $.fn.jquery);

    })(jQuery);
  });

</script>