4

想象一下下面的设置:一个页面有一个旧的 jQuery 版本(比如 1.5.2)——我无法控制——从我的服务器加载一个 Javascript 文件,该文件也需要 jQuery,但更新版本。(例如 1.8.3)现在我的脚本尝试执行以下操作:

var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", "http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js");
script.onreadystatechange = function() { // IE
  if (script.readyState === "complete" || script.readyState === "loaded") {
    ready();
  }
};
script.onload = function() { // other browsers
  ready();
};
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script);

ready函数然后检查是否$有正确的 jQuery 版本,如果有,它会将该 jQuery 实例绑定到另一个变量并返回$到原始 jQuery 版本,通过newjQuery = window.jQuery.noConflict(true);.

现在这一切正常,而且在加载“我的”jQuery 版本和将 $ 恢复到“他们的”jQuery 版本之间没有(外部)代码执行——至少在 Chrome、Firefox 等上。这种方法失败的地方是 Internet Explorer ,由于某种原因,它会处理至少 1 个可能并行运行的 Javascript 代码“滴答”。这往往会弄乱与“我的”jQuery 版本不兼容的代码,并且恰好在 IE 尚未执行就绪事件的 5 毫秒内执行。

这是一个示例小提琴:http: //jsfiddle.net/w5pPp/3/

在小提琴中,我每 10 毫秒测试一次当前绑定的 jQuery 版本。只有在 IE9 中,有时会出现短时间跨度$指“我的”jQuery,如“这不应该发生”日志所示。

现在我的问题是: 将“我的”jQuery 版本加载到它自己的变量中而不会在调用 noConflict 之前覆盖“他们的”jQuery 的短时间内执行页面代码时不会导致任何问题的最佳解决方案是什么?

4

1 回答 1

1

当您加载您的 jQuery 版本时,请尝试以下操作:

<!-- load your jQuery version -->
<script type="text/javascript" src="http://example.com/jquery-1.9.1.js"></script>
<script type="text/javascript">
    var $_mine = $.noConflict(true);
</script>

<!-- initialize their scripts -->
<script type="text/javascript" src="http://example.com/their-jquery.js"></script>
<script type="text/javascript" src="http://example.com/their-script.js"></script>

这应该会导致您$_mine可以使用您的 jQuery 版本,而不会与其他脚本冲突,并且它的使用$将引用过时的版本。

如上文评论所述,请参阅我可以在同一页面上使用多个版本的 jQuery 吗?有关更多详细信息/信息/示例。

编辑

根据上面的评论,这听起来好像不能解决您的问题。在这种情况下,我的怀疑是您实际上看到了 CDN 之间下载速度不同步的问题。尝试以相同的方式加载您和他们的 jQuery 版本,一个接一个。

换句话说:

function loadScript(variable_name, script_url) {
    var script = document.createElement("script");
    script.setAttribute("type", "text/javascript");
    script.setAttribute("src", script_url);
    script.onload = function() {
        if (variable_name != undefined) {
            window[variable_name] = jQuery.noConflict(true);
            console.log("after attach: " + window[variable_name].fn.jquery);
        }
    };
    (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script);
};

loadScript('newjQuery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js');
loadScript('$', 'http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js');
//loadScript(undefined, 'http://example.com/some/dependent/script/requiring-1.5.2.js');

这是一个工作的 jsFiddle,它显示了这种方法的工作原理:http: //jsfiddle.net/w5pPp/5/

诀窍是顺序加载这两个项目,并在 jQuery 版本到位后加载依赖项。

于 2013-03-28T18:27:14.980 回答