在js中加载jQuery,然后执行依赖于它的脚本

我有一个独特的问题 –

我正在设计一个创建小部件的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’中 – 它只是起作用。 虽然我不得不承认,我仍然不明白为什么它有效,这让我感到困扰……

您应首先检查以确保它们尚未使用jquery,例如:

 if (jQuery) { // jQuery is loaded } else { // jQuery is not loaded } 

其次,你应该确保你在没有冲突模式下使用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'); 

希望这可以帮助。

您最终使用的解决方案有效,但启动缓慢 ,而不是100%失败certificate 。 如果有人重写window.onload你的代码将无法运行。 当载入页面上的所有内容(包括图像)时,也会发生window.onload,这并不是您想要的。 您不希望脚本等待那么久。

幸运的是, ,可用于将其他脚本与它们耦合。

 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可用时,将完全调用该函数。 您的代码是失败certificate并快速启动。

调用jQuery函数时,不会加载或执行脚本。 这就是为什么你得到jQuery没有定义的错误。

我在动态加载脚本时回答了这个问题。 除了IE之外,所有浏览器的脚本都很简单。 只需添加一个onload事件监听器

使用LABjs 。 嵌入标签的工作原理是因为浏览器在看到任何脚本时加载并执行其中的任何脚本或由其引用,但这也意味着浏览器将阻塞,直到完成脚本。

如果您使用的是jQuery,则可以使用getScript() 。 Facebook有一个很好的例子来说明如何使用它 。 对于我在下面发布的原始版本,这是一个更易于管理的解决方案。

或者:

基于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 }); } );