代码之家  ›  专栏  ›  技术社区  ›  jasonpgignac

在JS中加载jquery,然后执行依赖它的脚本

  •  4
  • jasonpgignac  · 技术社区  · 15 年前

    我有一个独特的问题-

    我正在设计一个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的一个临时建议中,通过将调用本身放入一个“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();
    });
    

    At this point, as you can see, I don't even have to put it in an 'onload' - it just works. Though I have to admit, I still don't understand WHY it works, which bothers me...

    5 回复  |  直到 11 年前
        1
  •  1
  •   brendan    15 年前

    您应该首先检查以确保它们没有使用jQuery,所以如下:

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

    其次,你应该确保使用jQuery no conflict mode 并且不要使用$operator,因为它可能被另一个脚本库声明。

    然后嵌入,声明这个函数:

    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');
    

    希望这有帮助。

        2
  •  7
  •   gblazex    15 年前

    你最终使用的解决方案是工作,但是 起步慢 非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可用时准确调用函数。您的代码是防故障的,并且启动很快。

        3
  •  2
  •   Community CDub    8 年前

    调用jquery函数时未加载或执行脚本。这就是为什么您得到未定义jquery的错误。

    我回答了这个问题。 Loading Scripts Dynamically . 除了IEE之外,脚本对所有浏览器都很简单。只需添加一个加载事件侦听器即可。

        4
  •  1
  •   Evadne Wu    15 年前

    使用 LABjs . 嵌入 <script> tags work because the browser loads and executes whatever script in it or referenced by it upon seeing any of them, but that also means the browser will block until it is done with the script.

        5
  •  1
  •   user2449231    11 年前

    如果使用jQuery,可以使用 getScript() . Facebook has a good example on how to employ this . 对于我在下面发布的原始解决方案,这是一个更易于管理的解决方案。

    可选地:

    根据加拉姆巴拉兹的回答,你可以把他 include() 在jquery等事件中的函数 $(document).ready() 使用依赖行创建延迟脚本,而无需依赖额外的JS插件。我还添加了一个callbackonerror,如果你从google 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
            });
        }
    );