Javascript 如何让脚本执行等待 jquery 加载完成

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7486309/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 02:27:56  来源:igfitidea点击:

How to make script execution wait until jquery is loaded

javascriptjquery

提问by Amanda Kitson

I am having a problem where the page is loading so fast, that jquery hasn't finished loading before it is being called by a subsequent script. Is there a way to check for the existence of jquery and if it doesn't exist, wait for a moment and then try again?

我遇到了页面加载速度如此之快的问题,以至于 jquery 在被后续脚本调用之前还没有完成加载。有没有办法检查jquery是否存在,如果不存在,请稍等片刻,然后再试一次?



In response to the answers/comments below, I am posting some of the markup.

为了回应下面的答案/评论,我发布了一些标记。

The situation... asp.net masterpage and childpage.

情况... asp.net masterpage 和 childpage。

In the masterpage, I have a reference to jquery. Then in the content page, I have a reference to the page-specific script. When the page specific script is being loaded, it complains that "$ is undefined".

在母版页中,我引用了 jquery。然后在内容页面中,我引用了特定于页面的脚本。当加载页面特定脚本时,它会抱怨“$ 未定义”。

I put alerts at several points in the markup to see the order in which things were firing, and confirmed that it fires in this order:

我在标记中的几个点放置警报以查看事物触发的顺序,并确认它按以下顺序触发:

  1. Master page header.
  2. Child page content block 1 (located inside the head of the masterpage, but after the masterpage scripts are called).
  3. Child page content block 2.
  1. 母版页标题。
  2. 子页面内容块 1(位于母版页的头部内,但在母版页脚本被调用之后)。
  3. 子页面内容块 2。

Here is the markup at the top of the masterpage:

这是母版页顶部的标记:

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="SiteMaster" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>Reporting Portal</title>
    <link href="~/Styles/site.css" rel="stylesheet" type="text/css" />
    <link href="~/Styles/red/red.css" rel="stylesheet" type="text/css" />
    <script type="text/Scripts" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> 
    <script type="text/Scripts" language="javascript" src="../Scripts/jquery.dropdownPlain.js"></script>
    <script type="text/Scripts" language="javascript" src="../Scripts/facebox.js"></script>
    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
    <asp:ContentPlaceHolder ID="head" runat="server">
    </asp:ContentPlaceHolder>
</head>

Then in the body of the masterpage, there is an additional ContentPlaceHolder:

然后在母版页的正文中,还有一个额外的 ContentPlaceHolder:

 <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
                </asp:ContentPlaceHolder>

In the child page, it looks like so:

在子页面中,它看起来像这样:

<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Dashboard.aspx.cs" Inherits="Data.Dashboard" %>
<%@ Register src="../userControls/ucDropdownMenu.ascx" tagname="ucDropdownMenu" tagprefix="uc1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
    <link rel="stylesheet" type="text/css" href="../Styles/paserMap.css" />
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
***CONTENT HERE***
    <script src="../Scripts/Dashboard.js" type="text/javascript"></script>
</asp:Content>

Here is the content of the "../Script/Dashboard.js" file:

这是“../Script/Dashboard.js”文件的内容:

    $(document).ready(function () {

    $('.tgl:first').show(); // Show the first div

    //Description: East panel parent tab navigation
    $('.tabNav label').click(function () {
        $('.tabNav li').removeClass('active')
        $(this).parent().addClass('active');

        var index = $(this).parent('li').index();
        var divToggle = $('.ui-layout-content').children('div.tgl');

        //hide all subToggle divs
        divToggle.hide();
        divToggle.eq(index).show();
    });

});

采纳答案by Sander

edit

编辑

Could you try the correct type for your script tags? I see you use text/Scripts, which is not the right mimetype for javascript.

你可以为你的脚本标签尝试正确的类型吗?我看到你使用text/Scripts,这不是 javascript 的正确 mimetype。

Use this:

用这个:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> 
<script type="text/javascript" src="../Scripts/jquery.dropdownPlain.js"></script>
<script type="text/javascript" src="../Scripts/facebox.js"></script>

end edit

结束编辑

or you could take a look at require.jswhich is a loader for your javascript code.

或者你可以看看require.js,它是你的 javascript 代码的加载器。

depending on your project, this could however be a bit overkill

根据您的项目,这可能有点矫枉过正

回答by Darbio

Late to the party, and similar to Briguy37's question, but for future reference I use the following method and pass in the functions I want to defer until jQuery is loaded:

迟到了,类似于 Briguy37 的问题,但为了将来参考,我使用以下方法并传入我想推迟到 jQuery 加载的函数:

function defer(method) {
    if (window.jQuery) {
        method();
    } else {
        setTimeout(function() { defer(method) }, 50);
    }
}

It will recursively call the defer method every 50ms until window.jQueryexists at which time it exits and calls method()

它将每 50 毫秒递归调用一次 defer 方法,直到window.jQuery存在时它退出并调用method()

An example with an anonymous function:

一个匿名函数的例子:

defer(function () {
    alert("jQuery is now loaded");
});

回答by malko

you can use the defer attribute to load the script at the really end.

您可以使用 defer 属性在真正结束时加载脚本。

<script type='text/javascript' src='myscript.js' defer='defer'></script>

but normally loading your script in correct order should do the trick, so be sure to place jquery inclusion before your own script

但通常以正确的顺序加载脚本应该可以解决问题,所以一定要在你自己的脚本之前放置 jquery 包含

If your code is in the page and not in a separate js file so you have to execute your script only after the document is ready and encapsulating your code like this should work too:

如果您的代码在页面中而不是在单独的 js 文件中,那么您必须在文档准备好后才执行脚本,并且像这样封装您的代码应该也可以:

$(function(){
//here goes your code
});

回答by thdoan

Yet another way to do this, although Darbio's defer method is more flexible.

还有一种方法可以做到这一点,尽管 Darbio 的 defer 方法更灵活。

(function() {
  var nTimer = setInterval(function() {
    if (window.jQuery) {
      // Do something with jQuery
      clearInterval(nTimer);
    }
  }, 100);
})();

回答by moisrex

the easiest and safest way is to use something like this:

最简单和最安全的方法是使用这样的东西:

var waitForJQuery = setInterval(function () {
    if (typeof $ != 'undefined') {

        // place your code here.

        clearInterval(waitForJQuery);
    }
}, 10);

回答by Nigrimmist

You can try onload event. It raised when all scripts has been loaded :

您可以尝试 onload 事件。加载所有脚本后引发:

window.onload = function () {
   //jquery ready for use here
}

But keep in mind, that you may override others scripts where window.onload using.

但请记住,您可以覆盖使用 window.onload 的其他脚本。

回答by Annarfych

I have found that suggested solution only works while minding asynchronous code. Here is the version that would work in either case:

我发现建议的解决方案仅在考虑异步代码时才有效。这是适用于任何一种情况的版本:

document.addEventListener('DOMContentLoaded', function load() {
    if (!window.jQuery) return setTimeout(load, 50);
    //your synchronous or asynchronous jQuery-related code
}, false);

回答by Thomas Decaux

It's a common issue, imagine you use a cool PHP templating engine, so you have your base layout:

这是一个常见的问题,想象一下你使用了一个很酷的 PHP 模板引擎,所以你有你的基本布局:

HEADER
BODY ==> dynamic CONTENT/PAGE
FOOTER

And of course, you read somewhere it's better to load Javascript at the bottom of the page, so your dynamic content doesnot know who is jQuery (or the $).

当然,您在某处阅读最好在页面底部加载 Javascript,因此您的动态内容不知道谁是 jQuery(或 $)。

Also you read somewhere it's good to inline small Javascript, so imagine you need jQuery in a page, baboom, $ is not defined (.. yet ^^).

此外,您在某处读到内联小型 Javascript 很好,因此想象一下您需要在页面中使用 jQuery,baboom,$ 未定义(.. 尚未 ^^)。

I love the solution Facebook provides

我喜欢 Facebook 提供的解决方案

window.fbAsyncInit = function() { alert('FB is ready !'); }

So as a lazy programmer (I should say a good programmer ^^), you can use an equivalent (within your page):

所以作为一个懒惰的程序员(我应该说一个好的程序员 ^^),你可以使用一个等价的(在你的页面内):

window.jqReady = function() {}

And add at the bottom of your layout, after jQuery include

并在布局底部添加,在 jQuery 包含之后

if (window.hasOwnProperty('jqReady')) $(function() {window.jqReady();});

回答by Protector one

Rather than "wait" (which is usually done using setTimeout), you could also use the defining of the jQuery object in the window itself as a hook to execute your code that relies on it. This is achievable through a property definition, defined using Object.defineProperty.

除了“等待”(通常使用 完成setTimeout),您还可以使用窗口本身中 jQuery 对象的定义作为钩子来执行依赖于它的代码。这可以通过属性定义来实现,使用Object.defineProperty.

(function(){
  var _jQuery;
  Object.defineProperty(window, 'jQuery', {
    get: function() { return _jQuery; },
    set: function($) {
      _jQuery = $;

      // put code or call to function that uses jQuery here

    }
  });
})();

回答by Briguy37

Use:

用:

$(document).ready(function() {
    // put all your jQuery goodness in here.
});

Check out this for more info: http://www.learningjquery.com/2006/09/introducing-document-ready

查看更多信息:http: //www.learningjquery.com/2006/09/introducing-document-ready

Note: This should work as long as the script import for your JQuery library is above this call.

注意:只要您的 JQuery 库的脚本导入高于此调用,这应该可以工作。

Update:

更新:

If for some reason your code is not loading synchronously (which I have never run into, but apparently may be possible from the comment belowshould not happen), you could code it like the following.

如果由于某种原因您的代码没有同步加载(我从未遇到过,但显然可能从下面的评论中不应该发生),您可以像下面这样编写代码。

function yourFunctionToRun(){
    //Your JQuery goodness here
}

function runYourFunctionWhenJQueryIsLoaded() {
    if (window.$){
        //possibly some other JQuery checks to make sure that everything is loaded here

        yourFunctionToRun();
    } else {
        setTimeout(runYourFunctionWhenJQueryIsLoaded, 50);
    }
}

runYourFunctionWhenJQueryIsLoaded();