0

当使用 importjs() 类型的函数时(参见下面的示例),jQuery 似乎没有在它后面的代码之前加载。

这是一个示例 html 文件:

<html>
  <head></head>
  <body>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    <script type="text/javascript">
      function importjs(jsFile) {
        var body = document.getElementsByTagName('head').item(0);
        var scpt = document.createElement('script');
        scpt.src = jsFile;
        scpt.type = 'text/javascript';
        body.appendChild(scpt);
      }
      var f1="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js";
      //importjs(f1);
      var $j=jQuery;
      alert("hello stackoverflow!");
    </script>
  </body>
</html>

使用上面的代码,警报应该成功触发。

接下来,注释掉第一个脚本块,即显式加载 jQuery 的那个,并取消注释第二个脚本块中的 importjs(f1) 行。这一次,警报不会触发,至少在 firefox 和 safari 中是这样。

现在,在“var $j=jQuery”行之前添加一个额外的警报。对我来说,无论我等待多长时间,它都适用于两种浏览器。setTimeout 可能也可以解决问题,但它也不是编写此类程序的理想方法。

如果javascript是单线程的,为什么importjs会失败?是因为 importjs 创建的新元素在第一个块完成之前不会“执行”,还是应该在创建新元素后立即执行?

4

1 回答 1

7

这里有几个问题:

  • 你有 jQuery 重复,一个在 html 中,一个在 js 中
  • 如果您以这种方式加载脚本,则动态添加的 javascript 将不会立即可用,相关代码应位于回调函数中

    function importjs(jsFile, callback) {
        var head = document.getElementsByTagName('head')[0];
        var script = document.createElement('script');
        script.src = jsFile;
        script.type = 'text/javascript';
        script.onload = script.onreadystatechange = function() {
          // execute callback
          if (callback) callback();
          // prevent memory leak in IE
          script.onload = null;
          head.removeChild(script);
        };
        head.appendChild(script);
    }
    

    那么您应该将其用作:

    importjs("jquery.js", function(){
        // all jQuery dependant code
        // goes here...
    });​
    

更新

有一个更强大的包含 javascript 文件的解决方案,它允许您:

  • 包含多个相关的文件
  • 确保它们按顺序执行
  • 以非阻塞方式加载它们(与其他资源并行)

我仍在处理这个脚本,但现在几乎可以工作了。请务必检查一下。

它结合了不同技术的优势,在页面加载时间上提供了巨大的好处。这是一篇相关文章:加载脚本而不阻塞

语法是:

include(['jquery.js','jquery-ui.js'], myjQueryCode); // executed in order
于 2010-07-07T21:52:28.727 回答