我正在使用纯JavaScript进行测试,如果浏览器似乎支持HTML5,如果是这样,我想加载jQuery然后处理页面的其余部分。如果没有,将发生一些重定向。
<script type="text/javascript">
var canvas = document.createElement('canvas');
if (canvas && canvas.getContext && canvas.getContext('2d')) {
var s = document.getElementsByTagName('script')[0];
var jq = document.createElement('script');
jq.type = 'text/javascript';
jq.src = 'js/jquery.js';
s.parentNode.insertBefore(jq, s);
}
else {
// ... redirection ...
}
</script>
<script type="text/javascript">
$(function () {
//...
}
</script>
但上面的代码工作不正常,因为我收到了错误
Uncaught ReferenceError: $ is not defined
这清楚地表明jQuery库尚未加载。
为什么呢?在上面的代码中加载条件脚本有什么问题?
答案 0 :(得分:4)
这是使用document.write()
可能有意义的情况。您需要将此代码放在<body>
而不是<head>
:
<script type="text/javascript">
var canvas = document.createElement('canvas');
if (canvas && canvas.getContext && canvas.getContext('2d')) {
document.write( '<script src="js/jquery.js"><\/script>' );
}
else {
// ... redirection ...
}
</script>
<script type="text/javascript">
$(function () {
//...
}
</script>
或者,您可以使用普通的<script>
标记来加载jQuery,但在条件重定向之后将其设置为:
<script>
var canvas = document.createElement('canvas');
if( !( canvas && canvas.getContext && canvas.getContext('2d') ) ) {
// ... redirection ...
}
</script>
<script src="js/jquery.js"></script>
<script>
$(function () {
//...
}
</script>
使用这些方法中的任何一种,执行顺序为:
<script>
。jquery.js
,无论是使用document.write()
还是使用简单的<script>
代码。答案 1 :(得分:3)
当您插入脚本标记时,它将在后台加载,而不是立即加载,因此您的下一个脚本将在加载jQuery之前运行。您将需要附加一个监听器,以便您知道何时成功加载了jQuery,然后您可以运行使用jQuery的脚本。
这篇文章描述了如何知道加载动态加载脚本的时间:http://software.intel.com/en-us/blogs/2010/05/22/dynamically-load-javascript-with-load-completion-notification。
仅供参考,在您的具体情况下,您还可以拥有一个加载jQuery的静态脚本标记,但是将脚本检测是否在jQuery脚本标记之前重定向。那将是最简单的选择。
<script type="text/javascript">
var canvas = document.createElement('canvas');
if (!canvas || !canvas.getContext || !canvas.getContext('2d')) {
// redirect here or whatever
}
</script>
<script type="text/javascript" src="jquery.js">
</script>
<script type="text/javascript">
$(function () {
//...
}
</script>
答案 2 :(得分:1)
终于像魅力一样工作,我松了一口气!
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
<script type="text/javascript">
window.onload = function(){
var jqu = "$(console.log('worked'));";
var canvas = document.createElement('canvas');
if (canvas && canvas.getContext && canvas.getContext('2d')) {
var s = document.getElementsByTagName('head')[0];
var jq = document.createElement('script');
jq.setAttribute('type','text/javascript');
jq.innerHTML = jqu;
var jqLoad = document.createElement('script');
jqLoad.setAttribute('type','text/javascript');
jqLoad.setAttribute('src','jquery-1.10.0.js');
jqLoad.setAttribute('id','jqloader');
s.appendChild(jqLoad);
document.getElementById('jqloader').onload = function(){
console.log('loaded');
s.appendChild(jq);
}
}
else {
// ... redirection ...
}
console.log(document);
}
</script>
</head>
<body>
</body>
</html>
<强> jsbin Demo 强>
解释:
1-使用 dom函数来追加或插入元素总是最好的(动态且比其他任何东西更安全),并且不推荐使用document.write
。
2- 解析时间,您的脚本中的任何函数都将被评估,因此如果您有脚本并且尚未加载库,则会出现错误。
3-建议不要加载库并在同一标签中执行相关脚本。最好在另一个标签中脚本(完全加载完成后)以确保它能够正常工作。
document.onload
的4个事件确保文档已加载且 doms存在,因此可以将子项附加到它们。至于document.getElementById('jqloader').onload
,只是为了确保 jquery库完全加载并添加到文档中,然后才会添加脚本并进行评估
答案 3 :(得分:0)
正如其他人所说,你收到错误的原因是因为你已经异步加载了jQuery而且它还没有加载。
有两种方法可以达到你想要的效果。
您可以轮询window.jQuery,也可以使用异步加载器回调。
由于您只在检测到画布支持时才加载jQuery,因此您不必担心支持旧浏览器。
var async_script_load = function (s, callback) {
var script;
script = document.createElement("script");
script.async = "async";
if (s.scriptCharset) {
script.charset = s.scriptCharset;
}
script.src = s.url;
// Attach handlers for all browsers
script.onload = script.onreadystatechange = function () {
if (!script.readyState || /loaded|complete/.test(script.readyState)) {
// Handle memory leak in IE
script.onload = script.onreadystatechange = null;
// Remove the script
if (head && script.parentNode) {
head.removeChild(script);
}
// Dereference the script
script = undefined;
callback(200, "success");
}
};
// Use insertBefore instead of appendChild to circumvent an IE6 bug.
// This arises when a base node is used (#2709 and #4378).
head.insertBefore(script, head.firstChild);
};
async_loader({url:'http://tempuri.org/jquery.min.js'},function() {
//call jquery here.
});
对于轮询方法,它就像:
一样简单var checkJq = function() {
if(window.jQuery) {
//do jQuery
} else {
setTimeout(checkJq,100);
}
}
setTimeout(checkJq,100);