jquery加载的异步和就绪功能不起作用

Posted

技术标签:

【中文标题】jquery加载的异步和就绪功能不起作用【英文标题】:jquery loaded async and ready function not working 【发布时间】:2016-09-13 07:28:30 【问题描述】:

为了优化我的文档的负载,我用这样的方式加载jquery async

<script async type="text/javascript" src="js/jquery-1.12.3.min.js"></script>

然后我使用 jquery 调用脚本:

<script type="text/javascript">
    jQuery(document).ready(function() 
    App.init();
    OwlCarousel.initOwlCarousel();
    FancyBox.initFancybox();
    StyleSwitcher.initStyleSwitcher();

    );
</script>

它返回我未定义 jquery。

我不知道我应该使用什么,但我认为 .readyfunction 会等到所有文档都加载完毕后再调用它。

boostrap 库也一样,它告诉我 jquery 没有定义。

我试图要求脚本在最后加载,但它仍然无法正常工作。

我们将不胜感激。

【问题讨论】:

【参考方案1】:

由于 jquery 脚本是异步加载的,jquery 不会在您的脚本执行时加载。所以你需要通过订阅这样的加载事件来等待它加载:

<script async id="jquery" type="text/javascript" src="https://code.jquery.com/jquery-2.2.3.js"></script>

然后在这个元素上监听load 事件

<script type="text/javascript">
  document.getElementById('jquery').addEventListener('load', function () 
    App.init();
    OwlCarousel.initOwlCarousel();
    FancyBox.initFancybox();
    StyleSwitcher.initStyleSwitcher();
  );
</script>

但我不知道为什么有人想做这样的事情。

为了优化页面加载速度,最好把所有的 javascript 放在 body 的末尾,这样会先加载内容,如果同步加载,脚本不会延迟页面渲染事件。

编辑:我同意评论并认为上一段不是将 jQuery 加载到页面的最佳方式

【讨论】:

这不正确 - 正文末尾的 JS 将在内容加载后开始加载,这会导致“恐怖谷”:页面看起来已加载但是在 JS 也加载之前没有任何效果。这在特定情况下可能是可取的,但并非总是更好。同时,&lt;head&gt; 中的 &lt;script async ... 在您的内容加载时立即开始在后台下载 - 如果您希望内容快速交互,这是一个更好的模式。【参考方案2】:

问题Script Tag - async & defer很好地回答了您的问题。

简而言之,当某些其他脚本依赖于它时,您无法异步加载 jQuery 或其他库,而无需根据库执行脚本的额外异步处理。

【讨论】:

【参考方案3】:

这是我的解决方案:

    <script async type="text/javascript" src="path_to_jquery" id="jquery_script_tag">
    </script>

    <script>
    if ( !('jQuery' in window) )
    
        window.jQueryQueue = [];
        //define temporary jQuery function
        window.jQuery = function()
            //just save function parameters to queue
            jQueryQueue.push( arguments );
        
        document.getElementById('jquery_script_tag').addEventListener('load', function()
            //call jQuery with parameters saved in queue, after it loaded
            for ( var i in jQueryQueue )
                jQuery.apply( document, jQueryQueue[i] );
        );
    
    </script>

如果尚未定义,此代码将定义一个临时 jQuery 函数。该函数将所有 jQuery 函数调用保存到队列中,而真正的 jQuery 尚未加载(而不是调用未定义的 jQuery 函数)。并且当 jQuery 加载完毕后,它会调用队列中的 jQuery 函数,并使用与之前调用的参数相同的参数。

【讨论】:

请解释您的解决方案。出了什么问题以及您是如何解决的,而不是简单地粘贴代码。 此代码缓存所有 jQuery 函数调用到队列,而 jQuery 尚未加载(而不是调用未定义的 jQuery 函数)。当 jQuery 加载后 - 它使用与之前调用相同的参数调用 jQuery 您的解释应该包含在答案中,而不是在 cmets 中。请编辑您的答案并在其中包含解释。 英语对我来说很难。因此,我写了一个最低限度。新的解释可以理解吗? 这对于函数调用来说似乎是一个很好的解决方案,但是如果有像这样的属性调用呢? $.event.fixHooks ??你找到解决方法了吗?【参考方案4】:

jQuery 以及所有依赖 jQuery 的组件(包括 Bootstrap)都依赖于挂钩 DOMContentLoaded 事件来设置事件。

这意味着 jQuery(以及任何使用 $(function() ...) 的东西)必须DOMContentLoaded 触发之前下载,否则它永远不会连接它的事件。

反过来,这意味着&lt;script async ... 将不可靠,只要 jQuery 的下载时间比页面内容的下载时间长,就会中断。

不幸的是&lt;script defer ...doesn't work either 感谢jQuery 试图在document.readyState === "interactive" 立即触发。

您可以加载内容,然后通过将 &lt;script&gt; 放在 &lt;body&gt; 的末尾来加载 jQuery,但这会导致页面出现和任何 jQuery 触发之间出现明显的暂停 - 用户将无法点击任何东西,视觉组件都不会出现,等等。

【讨论】:

【参考方案5】:

这种方式很好用:

<script charset="utf-8" type="text/javascript">
var intervalID = window.setInterval(function()
  if(window.jQuery)
    clearInterval(intervalID);
    console.log('Loaded');
    /* Your code here */
  
,1000);
</script>

【讨论】:

【参考方案6】:

您在尝试访问 Jquery 时使用了异步加载它不是由浏览器加载的您可以在页面加载完成后访问 Jquery。

正常加载 Jquery 以解决您的问题。

【讨论】:

以上是关于jquery加载的异步和就绪功能不起作用的主要内容,如果未能解决你的问题,请参考以下文章

文档就绪功能在嵌套的 html 页面中不起作用:jQuery

Jquery加载功能不起作用初学者

为了删除预加载器的 jQuery .load(function) 和 .addClass 不起作用

首次加载页面时,Jquery UI 自动完成功能不起作用

当我将 html 数据从字符串加载到 webview 时,Jquery 功能不起作用

jQuery插件不起作用……“类型错误:'undefined'不是一个函数”