如果未加载,从外部源加载jQuery

7

从源代码中加载jQuery

我喜欢放弃本地的jquery.js文件,将其托管在其他地方。但是如果Google出现了问题怎么办?因此,让我们编写一个备用方案,如果jQuery仍未加载,则使用另一个来源...

我制作了这个测试用例,但似乎不起作用,也许有人可以帮助我:

http://jsfiddle.net/RBz4n


你能否更明确地说明你想要做什么? - Alastair Pitts
2
谷歌崩溃将导致互联网崩塌。别担心。 - Paolo Bergantino
像谷歌这样的CDN很少会崩溃。在编写代码时考虑到这种不太可能发生的事件只会使你的代码变得混乱无比 :( - NickG
5个回答

7

这个(来自HTML5 Boilerplate)相当有效:

<!-- Grab Google CDN's jQuery. fall back to local if necessary -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
<script>!window.jQuery && document.write(unescape('%3Cscript src="js/libs/jquery-1.4.2.js"%3E%3C/script%3E'))</script>

太棒了!非常感谢!这正是我在寻找的! - s15199d

4

以下是一个纯javascript的解决方案,它首先检测jQuery是否可用。如果不可用,则尝试CDN版本。如果CDN版本不可用,则尝试本地版本。处理404错误。我在一个无法确定网站是否已经包含jQuery的解决方案中使用它。

<script>
if (typeof jQuery === "undefined") {
  loadjQuery("//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js", verifyJQueryCdnLoaded);
} else 
  main();

function verifyJQueryCdnLoaded() {
  if (typeof jQuery === "undefined")
    loadjQuery("script/jquery-1.6.1.js", main);
  else
    main();
}

function loadjQuery(url, callback) {
  var script_tag = document.createElement('script');
  script_tag.setAttribute("src", url)
  script_tag.onload = callback; // Run callback once jQuery has loaded
  script_tag.onreadystatechange = function () { // Same thing but for IE
    if (this.readyState == 'complete' || this.readyState == 'loaded') callback();
  }
  script_tag.onerror = function() {
    loadjQuery("script/jquery-1.6.1.js", main);
  }
  document.getElementsByTagName("head")[0].appendChild(script_tag);
}

function main() {
  if (typeof jQuery === "undefined")
    alert("jQuery not loaded.");

  $(document).ready(function () {
    // Rest of your code here...
  });

}

</script>

我在编写用于 JIRA 的书签脚本时尝试使用类似这样的代码。"typeof jQuery === 'undefined'" 测试总是失败。原来 JIRA 使用了一些使用 jQuery 的脚本,比如 FancyBox,这导致 "jQuery" 被定义为一个函数,但 "$" 仍未定义。我更改了条件中的测试,然后 jQuery 就能够正确加载了。 - Mr. Lance E Sloan
1
哇,我从来没有见过这么多代码用来解决一个简单的问题。你一定喜欢打字... :) - NickG

2
您的脚本存在问题,即在测试jQuery是否已加载之前未等待脚本加载完成。请改用以下内容:

您的脚本存在问题,即在测试jQuery是否已加载之前未等待脚本加载完成。请改用以下内容:

function loadScript(src, callback) {
    var head=document.getElementsByTagName('head')[0];
    var script= document.createElement('script');
    script.type= 'text/javascript';
    script.onreadystatechange = function () {
        if (this.readyState == 'complete' || this.readyState == 'loaded') {
            callback();
        }
    }
    script.onload = callback;
    script.src = src;
    head.appendChild(script);
}

function isjQueryLoaded() {
    return (typeof jQuery !== 'undefined');
}

function tryLoadChain() {
    var chain = arguments;
    if (!isjQueryLoaded()) {
        if (chain.length) {
            loadScript(
                chain[0],
                function() {
                    tryLoadChain.apply(this, Array.prototype.slice.call(chain, 1));
                }
            );
        } else {
            alert('not loaded!');
        }
    } else {
        alert('loaded!');
    }
}

tryLoadChain(
    'https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js',
    'http://ajax.microsoft.com/ajax/jQuery/jquery-1.4.4.min.js',
    'mine.js');

嗯,我甚至可以删除tryLoadChain的源代码,但你的脚本仍然会弹出警告:已加载...对我没有用。 - Thom
不会。将第一个URL更改为404,它将停止执行。至少对我来说是这样。 - Robert Koritnik

1

问题

如果您使用Firebug并查看jQuery加载的位置,您会发现Google已经成功加载了它。为什么它似乎不起作用?因为请求是异步的,而您的脚本是同步运行的,它在第一个脚本加载之前执行所有步骤。

所以:

  1. jQuery不存在。
  2. 添加SCRIPT元素从Google加载(浏览器发送请求并继续执行脚本)
  3. jQuery不存在,添加另一个来源
  4. ...

等等。

解决方案

您应该做的是附加到您的脚本加载元素的onLoad事件,并在它们加载后检查jQuery。

与向互联网上的某个服务器发送请求并获取结果进行处理相比,脚本执行速度非常快。

其他注意事项

据我所读,您将使用此技术检测404时会遇到问题。建议的方法是使用Ajax(XHR),然后附加脚本元素并将接收到的内容添加到其中。这将是所有浏览器中最可靠的方法。


那么在检查 jQuery 是否加载之前设置 setTimeOut 有帮助吗? - Thom

0
罗杰的回答很荒谬。这里,使用这个替代方案,只需要两行代码。
<script>window.jQuery || document.write('<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"><\/script>')</script> 
<script>window.jQuery || document.write('<script src="Content/Scripts/jquery-1.9.1.min.js"><\/script>')</script>

有很多好的方法来将脚本节点附加到DOM上,而document.write不在其中。 - buley
@编辑 - 能解释一下吗?因为这里发布的几乎所有答案都依赖于document.write(),这似乎是做这个的标准方式。 - NickG
1
简而言之,因为它使您能够直接写入页面,很容易被滥用,如果被滥用,可能会成为安全漏洞。它在这里被投票下降,因为通常有更好的方法来完成相同的事情。另外,对于大型项目,请查看AMD样式加载,可能使用require.js等工具。 - Robert Christ
2
@RobertChrist - 顺便说一下,在那篇帖子中它本身就说这是document.write的合法用途之一。 - BornToCode

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接