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

时间:2011-06-06 13:42:33

标签: jquery file document-ready

我遇到了jQuery的document.ready触发器功能问题。我不确定这是由于jQuery还是由于浏览器的行为,但是这里发生了什么:当你尝试使用.append()方法动态加载脚本并为document.ready()设置处理程序时,在加载外部脚本/ css文件之前将触发document.ready()事件。这不适用于同一域中的脚本/ 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>

我们不会收到“对象”的提醒,而是会收到“未定义”的提醒。

谢谢你,亲切的问候。

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

3 个答案:

答案 0 :(得分:2)

<强> 1。使用DOM加载

正如尼克拉斯所说,你的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');
        });

});

答案 1 :(得分:2)

而不是使用:

$(document).ready(function()

您应该使用:

$(window).load(function()

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

答案 2 :(得分:1)

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

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

<body onload="function()">函数与.ready()函数不同,因为.ready()函数等待构建DOM(如前所述)并且<body onload="function()">函数等待对于实际开始加载或呈现的页面而不是DOM。 .load()函数的事件更加不同,因为它将资源,文件甚至代码片段加载到页面中。使用这种方法,理论上会很好,因为那样就不需要在身体上附加任何东西了。

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

我希望这会有所帮助。