使用内联脚本时未定义动态加载的jQuery [英] Dynamically loaded jQuery not defined when using inline script
问题描述
情况:
- 通过html文件
<head>
部分中的一个文件javascripts.js
将jQuery与其他脚本一起动态加载 - 每个html文件都有自己的javascript代码,该代码在html文件的
<body>
部分的jQuery(document).ready()
上执行
- jQuery is dynamically loaded together with other scripts by one file
javascripts.js
in the<head>
section of the html file - Each html file has it's own javascript code executed on
jQuery(document).ready()
in the<body>
section of the html file
问题:
- 错误:
<body>
部分中的 jQuery未定义 - 不能修改html文件(+1000个存在相同问题的文件)
- Error: jQuery is not defined for javascript in the
<body>
section - Modifying the html file is not an option (+1000 files with same problem)
示例html文件:
<html>
<head>
<title>JS test</title>
<script src="javascripts.js" type="text/javascript"></script>
</head>
<body>
<input type="text" class="date">
<script>
jQuery(document).ready(function() { // Error: jQuery not defined
jQuery('.date').datepicker();
});
</script>
</body>
</html>
javascripts.js:
// Load jQuery before any other javascript file
function loadJS(src, callback) {
var s = document.createElement('script');
s.src = src;
s.async = true;
s.onreadystatechange = s.onload = function() {
var state = s.readyState;
console.log("state: "+state);
if (!callback.done && (!state || /loaded|complete/.test(state))) {
callback.done = true;
callback();
}
};
document.getElementsByTagName('head')[0].appendChild(s);
}
loadJS('javascripts/jquery-1.8.3.min.js', function() {
var files = Array(
'javascripts/functions.js',
'javascripts/settings.js'
);
if (document.getElementsByTagName && document.createElement) {
var head = document.getElementsByTagName('head')[0];
for (i = 0; i < files.length; i++) {
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', files[i]);
script.async = true;
head.appendChild(script);
}
}
});
推荐答案
正如注释中所指出的,这种情况正在发生,因为您正在异步加载jQuery.异步意味着其余代码将被执行,因此在环境中存在jQuery之前,您的文档就绪处理程序(DRH)行正在运行.
This is happening, as many in the comments have pointed out, because you are loading jQuery asynchronously. Asynchronous means the rest of the code is executed, and so your document-ready handler (DRH) line is running before jQuery is present in the environment.
这是一种解决问题的真正方法.它涉及到临时替代jQuery,其工作只是记录DRH回调,直到jQuery到达为止.完成后,我们会将它们依次传递给jQuery.
Here's a really hacky way of resolving this. It involves making a temporary substitute of jQuery whose job is just to log the DRH callbacks until jQuery has arrived. When it does, we pass them in turn to jQuery.
JS:
//temporary jQuery substitute - just log incoming DRH callbacks
function jQuery(func) {
if (func) drh_callbacks.push(func);
return {ready: function(func) { drh_callbacks.push(func); }};
};
var $ = jQuery, drh_callbacks = [];
//asynchronously load jQuery
setTimeout(function() {
var scr = document.createElement('script');
scr.src = '//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js';
document.head.appendChild(scr);
scr.onload = function() {
$.each(drh_callbacks, function(i, func) { $(func); });
};
}, 2000);
HTML:
jQuery(document).ready(function() { alert('jQuery has loaded!'); });
提琴: http://jsfiddle.net/y7aE3/
在此示例中,注意drh_callbacks
是全局的,这显然是不好的.理想情况下,将其挂接到名称空间或诸如此类的名称上. mynamespace.drh_callbacks
.
Note in this example drh_callbacks
is global, which is obviously bad. Ideally hook it onto a namespace or something, e.g. mynamespace.drh_callbacks
.
这篇关于使用内联脚本时未定义动态加载的jQuery的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!