Internet Explorer尝试在加载库之前运行jQuery

时间:2011-02-10 20:16:20

标签: javascript jquery internet-explorer dom

我有一个小脚本

document.write("<html><head><script src='/js/jquery-1.4.2.min.js' type='text/javascript'></scr"
         + "ipt><script>alert($"+"().jquery);</scri" + "pt></head></html>");

但我在Internet Explorer中获得$ is undefined。我认为它会在加载库之前尝试运行脚本。

然而,这在Firefox中运行。请帮忙。

编辑:我打开一个新窗口并写入该窗口的文档。

11 个答案:

答案 0 :(得分:8)

以正确的方式创建<script>标记有什么问题? document.write是邪恶的,讨论的结束。

试试这个:

var load_script = function(options) {
  options.owner_document = options.owner_document || document;

  var script_tag = options.owner_document.createElement('script');
  script_tag.setAttribute('type', 'text/javascript');
  script_tag.setAttribute('src', options.src);
  script_tag.onload = function() {
    script_tag.onreadystatechange = null;
    options.callback && options.callback();
  };
  script_tag.onreadystatechange = function() {
    if (script_tag.readyState == 'loaded' || script_tag.readyState == 'complete') {
      script_tag.onload = null;
      options.callback && options.callback();
    }
  };
  options.owner_document.getElementsByTagName('head')[0].appendChild(script_tag);
};

如您所见,该片段上有一个简单的API:
src - 脚本的来源
owner_document - 将插入脚本的文档,默认为运行脚本的当前文档 回调 - 在脚本加载后运行的函数,任何需要src脚本的内容都可以在此闭包内运行。

示例用法:

// sample loading of jQuery
load_script({
  src: '/js/jquery-1.4.2.min.js',
  callback: function() {
    // jQuery is available at this point, run your code.

  }
});

或者,您可以使用requiere.jsLABjs

等加载器

答案 1 :(得分:4)

问题是您无意中触发了IE以非阻塞方式加载脚本。阅读本文以获取更多信息:Loading JavaScript without blocking

该页面建议您使用此代码在脚本加载完成后收到通知:

//Internet Explorer only
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "/js/jquery-1.4.2.min.js";
script.onreadystatechange = function(){
    if (script.readyState == "loaded" ||
            script.readyState == "complete"){
        script.onreadystatechange = null;
        // Your code goes here.
        alert("Script is ready!");
    }
};
document.body.appendChild(script);

答案 2 :(得分:1)

尝试在页面加载(window.onload)上运行第二个脚本,或尝试在正文中插入脚本,而不是在头部。 试试:

document.write("<html><head><script src='/js/jquery-1.4.2.min.js' type='text/javascript'></scr"
     + "ipt><script>window.onload = function(){alert($"+"().jquery);};</scri" + "pt></head></html>");

浏览器不会立即加载库(除非它在缓存中有它),因此在加载库之前可能会调用脚本。

答案 3 :(得分:1)

查看此解决方案: JavaScript's document.write Inline Script Execution Order

(还要注意评论,这很重要)

答案 4 :(得分:0)

您可以编写一个递归函数,等待加载jquery库,然后在加载库后执行任何代码。您可能希望添加一个条件,如果它太深,就会突破递归。

 document.write("<html><head><script src='/js/jquery-1.4.2.min.js' type='text/javascript'></scr"+ "ipt><script type='text/javascript'>var wait_for_jQuery = function() {if (typeof $ === 'undefined') {setTimeout('wait_for_jQuery()', 1000);} else {alert($"+"().jquery);}};  wait_for_jQuery(); </scri" + "pt></head></html>");

这里的工作示例:http://www.jsfiddle.net/YqTgM/36/

答案 5 :(得分:0)

您是否尝试将运行代码的脚本代码移动到body标记的末尾?根据{{​​3}}(YSlow的创作者):

  

脚本引起的问题是   他们阻止并行下载。该   HTTP / 1.1规范表明   浏览器下载不超过两个   每个主机名并行的组件。   如果您从多个图像提供图像   主机名,你可以得到两个以上   下载并行发生。而   然而,脚本正在下载   浏览器不会启动任何其他   下载,甚至是不同的   主机名。

所以结果看起来像......

document.write("<html><head><script src='/js/jquery-1.4.2.min.js' type='text/javascript'></scr"
     + "ipt></head><body><script>alert($"+"().jquery);</scri" + "pt></body></html>");

虽然我也主张不使用document.write()。

答案 6 :(得分:0)

答案 7 :(得分:0)

如果你想简化jQuery的条件加载,那里已经有很多选择;无需重新发明轮子。已经提到过RequireJS和LabJS。我正在使用Head.js,在尊重执行顺序的同时实现非阻塞加载的目标并不容易。

答案 8 :(得分:0)

您只是创建一个标记来引用jQuery,并且只要它创建的下一个语句是一个警报。您无法指定警报语句应在文件加载后运行。

答案 9 :(得分:-1)

一个简单的计时器应该这样做。

(function(){
  function wait() {
    if (typeof jQuery == 'undefined') {
        setTimeout(wait, 50);            
    } else {
        run(); // your code to execute
    }
  }

  wait();
})();

关于jsfiddle的示例:http://jsfiddle.net/madr/Gtafq/

答案 10 :(得分:-2)

<script></script>标记内部将您的代码包装在文档就绪函数中,以便在运行之前加载库。

 $(document).ready(function() {
   // put all your jQuery code here
 });