【问题标题】:How to make JS asynchronous while delaying the loading of the scripts?如何在延迟加载脚本的同时使 JS 异步?
【发布时间】:2017-02-17 11:29:34
【问题描述】:

我有一个 $(document).ready 函数(显示移动菜单),它必须等待 jQuery 导入。我注意到有时它会出现,有时它不取决于 jQuery 是否首先加载。 jQuery 导入异步加载。我想延迟 $(document).ready 函数,直到确定 jQuery 已经加载。我尝试使用 defer 和 async 但它似乎不起作用。我也尝试添加 setTimeout() 但它也不起作用。

<script async='async' src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js' type='text/javascript' />

 <script defer='defer' async='async' type='text/javascript'>
 ;(function ($, document, window) {   var
    // default settings object.
    defaults = {
      label: 'MENU',
      duplicate: true,
      duration: 200,
      easingOpen: 'swing',
      easingClose: 'swing',
      closedSymbol: '&#9658;',
      openedSymbol: '&#9660;',
      prependTo: 'body',
      parentTag: 'a',
      closeOnClick: false,
      allowParentLinks: false,
      nestedParentLinks: true,
      showChildren: false,
      init: function(){},
      open: function(){},
      close: function(){}
    },... </script>

【问题讨论】:

  • async 属性仅与外部脚本相关,即对内联没有影响 - defer 属性,根据 MDN,“应该只用于外部脚本”-
  • 我认为它不适用于内联脚本,但我只是尝试了一下。有没有办法让内联脚本等待 jQuery 导入?
  • 尝试在 jQuery 脚本标签中使用 onload="someFunc()",并将您拥有的代码包装在 function someFunc() { ... your code ... }
  • 我在那里没有看到 document.ready()。

标签: javascript jquery


【解决方案1】:

问题是您将 jQuery 作为异步加载:

<script async='async'  <----------- this is the problem
    src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js'
    type='text/javascript'
/>

async 属性告诉您的浏览器可以在执行页面上的所有其他 javascript 代码后稍后加载此文件。解决办法是去掉async

但是不推荐异步吗?

是的,但仅适用于您页面上的其他脚本不依赖的脚本。对于需要确定已加载的 jQuery 等库,不应使用 async

但是如果浏览器等待 jQuery 会不会减慢页面加载速度?

是的,解决方案是将所有脚本标记移到页面底部,在&lt;head&gt; 之外,就在&lt;body&gt; 标记关闭之前:

<html>
<head></head>
<body>
   some stuff...



 <script src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js' type='text/javascript' />
 <script type='text/javascript'>
 ;(function ($, document, window) {   var
    // default settings object.
    defaults = {
      label: 'MENU',
      duplicate: true,
      duration: 200,
      easingOpen: 'swing',
      easingClose: 'swing',
      closedSymbol: '&#9658;',
      openedSymbol: '&#9660;',
      prependTo: 'body',
      parentTag: 'a',
      closeOnClick: false,
      allowParentLinks: false,
      nestedParentLinks: true,
      showChildren: false,
      init: function(){},
      open: function(){},
      close: function(){}
    },... </script>
</body>
</html>

但我(或我的老板)不喜欢头脑之外的脚本!!

好吧,您仍然可以将脚本放在头脑中,但它有点复杂。基本上你需要监听 jquery script 标签的 onload 事件。但这意味着您需要动态创建标签,而不是在 html 中硬编码:

<html>
<head>
  <script>
    var jq = document.createElement('script');
    jq.src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js";

    jq.async = true;  // you can still load as async!

    jq.onload =  function () {
      (function ($, document, window) {   var
      // default settings object.
      defaults = {
        label: 'MENU',
        duplicate: true,
        duration: 200,
        easingOpen: 'swing',
        easingClose: 'swing',
        closedSymbol: '&#9658;',
        openedSymbol: '&#9660;',
        prependTo: 'body',
        parentTag: 'a',
        closeOnClick: false,
        allowParentLinks: false,
        nestedParentLinks: true,
        showChildren: false,
        init: function(){},
        open: function(){},
        close: function(){}
      },... 
    };
    document.head.appendChild(jq);
  </script>
</head>
<body> .... </body>
</html>

【讨论】:

  • 对于第二种方法,我应该只将所有脚本放在头部吗?我在正文中尝试过,但其他脚本似乎显示错误。
  • @Vinz:什么错误?如果他们不依赖 jQuery,那么如果将 jQuery 移动到正文,他们就没有理由出错。哎呀,您甚至可以完全删除 jQuery,它们应该继续工作。如果它们依赖于 jQuery,那么您需要将它们全部移动到正文中。仅供参考,雅虎和谷歌页面速度测试都建议不要将 js 放在头部,而是将它们放在正文的底部
  • 我只是做了第一种方法。谢谢!
【解决方案2】:

将您的$(document).ready 函数作为页面上的最后一个脚本。

您可能需要考虑将加载 JQuery 的脚本放在文档的 &lt;head&gt; 中,以确保它在被调用之前加载。

【讨论】:

  • 他已经这样做了。问题是他将 jQuery 加载为async(参见他的脚本标签),它告诉浏览器可以先在标签之后执行代码,而无需等待 jQuery 完成加载
  • 是的,在正文关闭之前脚本已经在底部了。
猜你喜欢
  • 2016-10-03
  • 1970-01-01
  • 2015-06-17
  • 2012-03-25
  • 2017-07-08
  • 1970-01-01
  • 1970-01-01
  • 2016-07-09
  • 2013-08-01
相关资源
最近更新 更多