如果使用 document.write,则无法以编程方式插入 js

Posted

技术标签:

【中文标题】如果使用 document.write,则无法以编程方式插入 js【英文标题】:Can't insert js programmatically if it uses document.write 【发布时间】:2012-02-03 21:47:16 【问题描述】:

我正在尝试以编程方式插入 js 文件,使用 jquery 和类似的东西:

var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = 'http://someurl/test.js';
$('body').append(script);

如果 test.js 包含 alert 或一些简单的代码,它可以正常工作,但是如果文件 test.js 包含 document.write,并且包含 js 的文件托管在 test 之外的另一个域上。 js(或本地主机),没有任何反应,萤火虫显示错误:

从异步加载的外部调用 document.write() 脚本被忽略了。

如果 test.js 和包含它的文件托管在同一个域上,在 chrome 上它仍然无法工作,但在 firefox 上,document.write 执行得很好,但页面永远保持“加载”状态,并且嗅探器显示请求所有处于“待处理”状态的文件。

我还可以尝试哪些其他以编程方式包含 js 文件的方法?

【问题讨论】:

问题不在于您如何包含文件,而在于页面加载后正在执行document.write() 【参考方案1】:

Document.write 仅适用于加载 html 时的同步任务(第一次),绝不适用于您尝试执行的异步任务。

【讨论】:

没错;但是如果可以修改外部脚本,请使用innerHTML而不是像@ChamikaSandamal所说的document.write。【参考方案2】:

使用innerHTML 而不是document,write

并使用以下代码注册脚本,

(function() 
    var jq = document.createElement('script');
    jq.type = 'text/javascript';
    jq.async = true;
    jq.src = 'http://someurl/test.js';
    var s = document.body.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(jq, s);
)();

【讨论】:

【参考方案3】:

您插入 JavaScript 的方法没有任何问题。 document.write 有点烂。它仅适用于同步任务,因此将document.write 放在单独的脚本文件中是自找麻烦。无论如何,人们都会这样做。我最常看到的解决方案是覆盖document.write

【讨论】:

【参考方案4】:

您要做的是将<script> DOM 元素动态插入到 HEAD 元素中。我有这个脚本。例如,这是一个竞争条件,但你明白了。使用 URL 呼叫 load_js。这适用于许多现代 API,它是跨域 JavaScript 的最佳朋友。

<html>
    <head>
        <script>
            var load_js = function(data, callback)
            
                    var head = document.getElementsByTagName("head")[0];

                    var script = document.createElement("script");
                    script.type = "text/javascript";
                    script.src = data;
                    head.appendChild(script);

                    if(callback != undefined)
                            callback();
            

            load_js("http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js");

            setTimeout(function() 
                $('body').html('loaded');
            , 1000);
        </script>
    </head>

    <body></body>
</html>

【讨论】:

嗨 Eric,1>这会加载 jQuery,但如果我将任何函数作为第二个参数传递给 load_js(),则在加载 js 后不会调用该函数。 2> 什么时候调用 load_js 和 setTimeout ?能说说这里的执行流程吗? Umesh,第2个参数在加载JS后不调用,只是在DOM元素被注入之后。为了在加载脚本后获得回调,您需要 JSONP。 en.wikipedia.org/wiki/JSONP 如果您使用它,Google 的 JS API 会为您处理,但以上只是一个示例。这里:925html.com/code/using-googles-ajax-apis 一旦你有了 jQuery,你可以使用 jQuery 将更多的 Eric,你说的真是太棒了:)我正在关注你的博客..你为什么不写更多这样的东西..

以上是关于如果使用 document.write,则无法以编程方式插入 js的主要内容,如果未能解决你的问题,请参考以下文章

无法让 document.write 使用 ajax

“将图像另存为..”在使用 window.open() 和 document.write() 时无法在 Google Chrome 中运行

使用可能包含 document.write 的 src 动态添加脚本标签

使用可能包含 document.write 的 src 动态添加脚本标签

document.write

控制来自第三方的 document.write 调用的范围