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

时间:2010-06-28 00:24:53

标签: javascript 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'中 - 它只是起作用。虽然我不得不承认,但我仍然不明白为什么它有效,这让我困扰......

5 个答案:

答案 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
        });
    }
);