2015-07-05 28 views
2

我正在尝试编写一些脚本后退代码,以便如果jQuery和jQuery Validator不能从CDN获得,我将加载本地版本。请注意,以下脚本位于单独的文件中以支持内容安全策略(CSP)。如何等待document.write来完成

(window.jQuery || document.write('<script src="/js/jquery.js"><\/script>')); 
($.validator || document.write('<script src="/js/jquery-validate.js"><\/script>')); 

如果jQuery不可用,新的脚本标记被写入到文档的末尾,但是接下来的行错误说$是未定义的。如何在执行下一行之前等待文档写入完成加载文档?

+1

删除[标签:jQuery的验证]因为这个问题/问题/解决方案标签有没有什么特别的做这个插件,可以适用于任何CDN托管脚本。 – Sparky

回答

4

您应该利用<script>onload事件。取而代之的ducoment.write,通过DOM操作的脚本标签添加到文档:

var s = document.createElement('script'); 
s.onload = function() { 
    // jQuery is now loaded and can be used 
} 
s.src = '/js/jquery.js'; 
document.getElementsByTagName('head')[0].appendChild(s); 

UPDATE:

回答你的问题“如何等待文件撰写”是你不必因为document.write是同步的。 document.write后面的下一行只有在写入方法写完后才会执行。但是,如果您将<script>标记写入文档并且具有src属性,则资源的加载(src指向的地方)将是异步的,并且在写入完成(并行)后将开始执行下一个语句。因为不可能预先知道资源加载需要多长时间,所以确保所有内容都可从外部脚本获得的唯一可行方法是onload事件。

+1

@ zlumer谢谢,错字修正,请参阅我的更新。 – marekful

+1

感谢,upvoted&删除我的评论过时。 – zlumer

3

document.write已经阻止执行,直到信息被解析和处理。所以你不需要任何额外的代码为你的例子。

另一方面,我会建议使用DOM注入而不是document.writedocument.write延迟CSS处理,并可能导致FOUC(未格式化内容的Flash)。

DOM注射可以做如下:

var scriptElm = document.createElement('script'); 
scriptElm.src = '/js/jquery.js'; 
document.getElementsByTagName('head')[0].appendChild(scriptElm); 

// Check if jQuery is loaded here 
+1

但是,在您的代码注释中提到“检查jQuery是否已加载”时,OP需要等待加载。你是怎样做的? – nnnnnn

+0

那么如何在第二行未定义$? –

+3

@RehanSaeed'$'直到脚本被加载后才会被定义。 'document.write()'调用已成功完成,但脚本在执行第二行时尚未加载 – zlumer