为什么来自动态append()的jQuery的document.ready不等待外部脚本/样式?

发布于 11-14 14:43 字数 1331 浏览 4 评论 0原文

我对 jQuery 的 document.ready 触发函数有疑问。我不确定这是由于 jQuery 还是由于浏览器的行为,但会发生以下情况:当您尝试使用 .append() 方法动态加载脚本并为 document.ready() 设置处理程序时, document.ready() 事件将在加载外部脚本/css 文件之前被触发。这不适用于同一域中的脚本/CSS 文件 - 如果它们位于同一域中,则 document.ready 触发器将等待它们加载。

下面是显示错误的代码示例:

<html>
    <head>
        <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
    </head>
    <body>
    <script type="text/javascript">
        $(document).ready(function() {
            var html = '<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js" type="text/javascript"><' + '/script>'
                     + '<script type="text/javascript">$(document).ready(function() {alert(typeof jQuery.ui);})</' + 'script>';

            $('body').append(html);
        });
    </script>
    </body>
</html>

我们没有收到带有“object”的警报,而是收到带有“undefined”的警报。

谢谢您和亲切的问候。

编辑:其他人遇到了类似的问题,他们使用的解决方案首先加载外部脚本,然后加载 HTML/纯 JS。链接是: http:// snipplr.com/view/43449/load-external-scripts-first-for-injected-dom-html-content/。不管怎样,我对这个解决方案并不满意,因为它意味着代码中的一些更改,并且我不确定它是否在所有浏览器上 100% 可靠。

I'm having an issue with jQuery's document.ready trigger function. I'm not sure if this is due to jQuery or due to the browsers' behavior but here's what happens: when you try to dynamically load a script using the .append() method and also set a handler for document.ready(), the document.ready() event will be triggered before the external script/css file will be loaded. This does not apply for script/css files that are on the same domain - if they are on the same domain the document.ready trigger will wait for them to load.

Here's a sample of code that shows the error:

<html>
    <head>
        <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
    </head>
    <body>
    <script type="text/javascript">
        $(document).ready(function() {
            var html = '<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js" type="text/javascript"><' + '/script>'
                     + '<script type="text/javascript">$(document).ready(function() {alert(typeof jQuery.ui);})</' + 'script>';

            $('body').append(html);
        });
    </script>
    </body>
</html>

Instead of getting an alert with "object" we get an alert with "undefined".

Thank you and kind regards.

EDIT: Someone else experienced a similar problem and they used a solution that first loads the external scripts and then loads the HTML/plain JS. The link is: http://snipplr.com/view/43449/load-external-scripts-first-for-injected-dom-html-content/. Anyway, I'm not happy with this solution as it implies several changes in the code and I'm not sure if it's 100% reliable on all browsers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

清醇2024-11-21 14:43:55

1.加载 DOM

正如 Niklas 所说,你的 dom 已经准备好了。

您可以应用此方法

jQuery.getScript("url",function () { /* on success.. do this */ });

http://api.jquery.com/jQuery.getScript/

< a href="http://jsfiddle.net/4crRw/" rel="nofollow">http://jsfiddle.net/4crRw/

2.将它们添加在一起

http://jsfiddle.net/4crRw/2/

$(document).ready(function ()
{
    var alertWhenDone = function (requiredObjects, callback)
    {
        this.callback = callback;
        this.required = requiredObjects;
        this.addDone = function (label) {
            // remove it from the list
            this.required.splice(this.required.indexOf(label),1);
            if (this.required.length === 0)
            {
                this.callback();
            }
        };
        return this;
    };
    var alertdone = alertWhenDone(['ui','swfloader','font'], function () {
        alert('done');
    });
    jQuery.getScript('http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js',
        function () {
            alertdone.addDone('ui');
        });

    jQuery.getScript('https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js',
        function () {
            alertdone.addDone('swfloader');
        });

    jQuery.getScript('https://ajax.googleapis.com/ajax/libs/webfont/1.0.19/webfont.js',
        function () {
            alertdone.addDone('font');
        });

});

1. Loading with the DOM

As Niklas said, your dom is already ready.

You may apply this method

jQuery.getScript("url",function () { /* on success.. do this */ });

http://api.jquery.com/jQuery.getScript/

http://jsfiddle.net/4crRw/

2. Adding them together

http://jsfiddle.net/4crRw/2/

$(document).ready(function ()
{
    var alertWhenDone = function (requiredObjects, callback)
    {
        this.callback = callback;
        this.required = requiredObjects;
        this.addDone = function (label) {
            // remove it from the list
            this.required.splice(this.required.indexOf(label),1);
            if (this.required.length === 0)
            {
                this.callback();
            }
        };
        return this;
    };
    var alertdone = alertWhenDone(['ui','swfloader','font'], function () {
        alert('done');
    });
    jQuery.getScript('http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js',
        function () {
            alertdone.addDone('ui');
        });

    jQuery.getScript('https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js',
        function () {
            alertdone.addDone('swfloader');
        });

    jQuery.getScript('https://ajax.googleapis.com/ajax/libs/webfont/1.0.19/webfont.js',
        function () {
            alertdone.addDone('font');
        });

});
哥,最终变帅啦2024-11-21 14:43:55

而不是使用:

$(document).ready(function()

您应该使用:

$(window).load(function()

它将等待外部内容已加载(例如图像,字体)

Instead of using:

$(document).ready(function()

You should use:

$(window).load(function()

It will wait for external content to be already loaded (e.g. images, fonts)

疧_╮線2024-11-21 14:43:55

jquery .ready() 函数在 DOM 层次结构完全加载后立即启动。这通常发生在所有图像加载之后。它不等到脚本/CSS文档加载的原因是因为它们是“链接的”,这意味着它们是从外部加载的,然后保留在缓存中,而主代码被转换为可查看的页面。

如果您当前在 $document.ready(function{}) 中的脚本依赖于外部资源,请使用 $document.ready($document.load(asset),function{}) 如果您想加载特定文档/资产,则加载函数或脚本。

函数与 .ready() 函数不同,因为 .ready()函数等待 DOM 构建(如我之前所说), 函数等待页面(而不是 DOM)实际开始加载或渲染。 .load() 函数更加不同,因为它将资源、文件甚至代码片段加载到页面中。从理论上讲,使用这种方法会很好,因为这样就不需要在正文中附加任何内容。

更多信息(以及更全面的解释)可以在 http://api.jquery.com/ready/< /a> 和 http://api.jquery.com/load/

我希望这有帮助。

The jquery .ready() function, starts as soon as the DOM hierarchy is completely loaded. This usually happens after all images have been loaded. The reason that it does not wait until the scripts/css documents are loaded is because they are "linked" meaning they are loaded externally and then remain in cache while the main code is translated into a view-able page.

If the script you currently have in the $document.ready(function{}) relies on external assets, use the <body onload="function()"> or $document.ready($document.load(asset),function{}) if you want to load specific documents/assets then the function or script.

The <body onload="function()"> function is different from the .ready() function because the .ready() function waits for the DOM to be built (as I said earlier) and the <body onload="function()"> function waits for the page, not the DOM, to actually start to load or render. The .load() function is event more different, because it load assets, files, or even snips of code into the page. Using this method, in theory would be good because then there should be no need to append anything to the body.

Greater information (and a more thorough explanation) can be found at http://api.jquery.com/ready/ and http://api.jquery.com/load/.

I hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文