我有一个独特的问题 -
我正在设计一个创建小部件的Web应用程序,然后用户可以将这些小部件嵌入到他们自己的页面中(主要是博客文章)。我希望他们只需要嵌入一行,所以我只是将该行作为include语句,从我的服务器上取下Javascript。
问题是,我正在使用jQuery构建窗口小部件代码,我需要加载jQuery插件,因为我显然不知道我的用户是否可以使用它。我认为'这应该很简单'....
function includeJavaScript(jsFile) {
var script = document.createElement('script');
script.src = jsFile;
script.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(script);
}
includeJavaScript('http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js');
jQuery();
所以,我将jQuery文件附加到头部,然后尝试运行jQuery函数。麻烦的是,这不起作用!每次运行它时,我都会收到错误,即未定义变量jQuery。我尝试了一些事情。我尝试将jQuery函数放在onLoad触发器中,以便整个页面(包括,可能是jQuery文件)在调用我的脚本之前加载。我尝试将jQuery函数放在一个单独的文件中,并在加载jQuery lib文件后加载它。但是我觉得我错过了一些简单的东西 - 我是jQuery的新手,所以如果我遗漏了一些明显的东西,我道歉......
修改
好的,我尝试了digitalFresh提供的建议,如下(使用Safari 5,如果有帮助),但我仍然得到同样的错误?
function test() {
jQuery()
}
var script = document.createElement("script");
script.type = "text/javascript";
script.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js';
script.onload = test(); //execute
document.body.appendChild(script);
修改
好的,我最终得到了它的工作,在Brendan的一个随意的建议中,将调用ITSELF置于'onload'处理程序中,如下所示:
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}
addLoadEvent( function() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js';
document.body.appendChild(script);
jQuery();
});
此时,正如您所看到的,我甚至不必将其置于'onload'中 - 它只是起作用。虽然我不得不承认,但我仍然不明白为什么它有效,这让我困扰......
答案 0 :(得分:7)
您最终使用的解决方案有效,但启动缓慢,不是100%失败证明。如果有人重写window.onload你的代码将无法运行。当载入页面上的所有内容(包括图像)时,也会发生window.onload,这并不是您想要的。你不希望你的脚本等待那么久。
幸运的是< script>元素有自己的onload(ready)事件,可用于将其他脚本与它们耦合。
function include(file, callback) {
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = file;
script.onload = script.onreadystatechange = function() {
// execute dependent code
if (callback) callback();
// prevent memory leak in IE
head.removeChild(script);
script.onload = null;
};
head.appendChild(script);
}
include('http://ajax.googleapis.com/.../jquery.min.js', myFunction);
在这种情况下,当jquery可用时,将完全调用该函数。您的代码是失败证明并快速启动。
答案 1 :(得分:2)
调用jQuery函数时,不会加载或执行脚本。这就是为什么你得到jQuery未定义的错误。
我在Loading Scripts Dynamically上回答了这个问题。除了IE之外,所有浏览器的脚本都很简单。只需添加一个onload事件监听器
答案 2 :(得分:1)
使用LABjs。嵌入<script>
标记是有效的,因为浏览器在看到任何脚本时会加载并执行其中的任何脚本,或者在看到任何脚本时引用它们,但这也意味着浏览器将阻塞,直到完成脚本为止。
答案 3 :(得分:1)
您应首先检查以确保它们尚未使用jquery,例如:
if (jQuery) {
// jQuery is loaded
} else {
// jQuery is not loaded
}
其次,你应该确保在no conflict mode中使用jQuery,并且不要使用$运算符,因为它可能被另一个脚本库声明。
然后嵌入,声明这个函数:
function load_script (url)
{
var xmlhttp;
try {
// Mozilla / Safari / IE7
xmlhttp = new XMLHttpRequest();
} catch (e) {
//Other IE
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
xmlhttp.open('GET', url, false); x.send('');
eval(xmlhttp.responseText);
var s = xmlhttp.responseText.split(/\n/);
var r = /^function\s*([a-z_]+)/i;
for (var i = 0; i < s.length; i++)
{
var m = r.exec(s[i]);
if (m != null)
window[m[1]] = eval(m[1]);
}
}
然后叫它:
load_script('http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js');
希望这有帮助。
答案 4 :(得分:1)
如果您使用的是jQuery,则可以使用getScript()。 Facebook has a good example on how to employ this。对于我在下面发布的原始文件,这是一个更易于管理的解决方案。
可替换地:
根据galambalazs的回答,你可以将他的include()
函数包装在像jQuery $(document).ready()
之类的事件中,以创建具有依赖行的延迟脚本,而不必依赖额外的JS插件。我还添加了一个callbackOnError,如果你是从谷歌CDN获取的话,这很方便。
/* galambalazs's include() */
function include(file, callback, callbackOnError) {
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = file;
script.onload = script.onreadystatechange = function() {
// execute dependent code
if (callback) callback();
// prevent memory leak in IE
head.removeChild(script);
script.onload = null;
script.onerror = null;
};
script.onerror = function() {
if(callbackOnError) callbackOnError();
// prevent memory leak in IE
head.removeChild(script);
script.onload = null;
script.onerror = null;
};
head.appendChild(script);
}
/* If you need a deferred inline script, this will work */
function init() {
// Insert Code
}
/* Example with callback */
$(document).ready(function() {
include('something.js', init);
});
/* Maybe I want something on window.load() */
$(window).load(function() {
// Without a callback
include('whatever.js');
});
/* Or use an event to load and initialize script when it's needed */
$(".nearAButton").hover(include('button.js',function() {initButtonJS()}));
function initButtonJS() {
$(".nearAButton").off("mouseenter mouseleave");
}
/* Attempt to load Google Code, on fail load local */
include(
'//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js',
function () {
// Inline Callback
},
function () {
include('/local/jquery-ui-1.10.3.custom.min.js', function () {
// Inline Callback
});
}
);