在ajax调用之后加载脚本的位置在哪里? (终极版)

时间:2011-11-27 03:10:01

标签: javascript ajax jquery

previous SO post解决方案中发现了动态加载包含嵌入式<script>标记的网页的问题。然而,正如我所发现的那样,这不是一个全面的解决方案。打破代码的场景(请查看以前的帖子及其解决方案),看起来像这样:

- svc.html -

<script type="text/javascript" src="/plugin.js" css="/plugin.css"></script>
<script type="text/javascript">
plugin_method();
</script>

<div id='inner'>
dynamically loaded content
</div>

其中plugin.js与以前相同,但包含plugin_method的函数定义。

问题似乎是当脚本节点被添加到文档中时:

target[0].appendChild(scriptNode);

代码不会立即执行。如果(如上一篇文章中)svc.html页面中只有一个脚本标记,一切正常,但一旦有第二个,插件中的$('script:last')不再指向正确脚本,因此无法加载样式表。

此外,第二个脚本标记的主体似乎在第一个脚本的代码之前执行,因此方法调用失败(因为函数尚未定义)。

我找到了几个链接,我正在考虑这个链接:

http://requirejs.org/docs/why.html http://unixpapa.com/js/dyna.html

任何人的想法?

1 个答案:

答案 0 :(得分:0)

好的,所以答案是我们不能只遍历脚本列表 - 我们需要在 load 事件中进行递归,如下所示:

// inspired by Kevin B's suggestions
// at: http://stackoverflow.com/questions/8234215/where-are-scripts-loaded-after-an-ajax-call

(function ($) {
    $.fn.loadWithJs = function (o) {
        console.log(".loadWithJs - started");
        var target = this;

        target.addScript = function (scripts, n, success) {
            var script = scripts[n];

            var scriptNode = document.createElement('script');
            for (var i = 0; i < script.attributes.length; i++) {
                var attr = script.attributes[i];
                $(scriptNode).attr(attr.name, attr.value);
            }
            scriptNode.appendChild(
                document.createTextNode($(script).html())
            );
            $(scriptNode).load(function () {
                if (++n < scripts.length)
                    target.addScript(scripts, n, success);
                else if (success)
                    success();
            });
            target[0].appendChild(scriptNode);
        };

        var success = o.success;
        o.success = function (html) {
            // convert script tags
            var h = $('<div />').append(
                html.replace(/<(\/)?script/ig, "<$1codex")
            );
            // detach script divs from html
            var scripts = h.find("codex").detach();
            // populate target
            target.html(h.children());
            // start recursive loading of scripts
            target.addScript(scripts, 0, success);
        };

        $.ajax(o);
    };
})(jQuery);

*编辑*

好吧,这也不起作用。如果我们在main.html的末尾添加一个脚本标记,它会在第一个load事件触发之前(以及脚本运行之前)添加到$('script')数组中,因此$( 'script:last')仍然是错误的。 GRR ...