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



jQuery的document.ready触发器函数有问题。我不确定这是由于jQuery还是由于浏览器的行为,但情况如下:当您尝试使用.append()方法动态加载脚本并为document.ready()设置处理程序时,document.ready()事件将在加载外部script/css文件之前触发。这不适用于同一域上的script/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/plain JS。链接是:http://snipplr.com/view/43449/load-external-scripts-first-for-injected-dom-html-content/.无论如何,我对这个解决方案不满意,因为它意味着代码中的一些更改,我不确定它是否在所有浏览器上都是100%可靠的。

1。使用DOM加载

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

您可以应用此方法

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

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

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');
        });
});

而不是使用:

$(document).ready(function()

您应该使用:

$(window).load(function()

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

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

如果当前$document.ready(function{})中的脚本依赖于外部资源,请使用<body onload="function()">$document.ready($document.load(asset),function{})。如果要加载特定的文档/资源,则使用函数或脚本。

<body onload="function()">函数与.ready()函数不同,因为.ready()函数等待构建DOM(正如我前面所说),而<body onload="function()">函数等待页面而不是DOM实际开始加载或渲染。.load()函数与事件更为不同,因为它将资产、文件甚至代码片段加载到页面中。从理论上讲,使用这种方法是很好的,因为这样就不需要在身体上附加任何东西。

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

我希望这能有所帮助。

最新更新