25

我们有一个带有依赖原型的遗留代码的应用程序,但我们发现它对于我们想要使用它的大多数地方来说太“重”了,并且发现 jQuery 更适合我们的工作方式。所以我们正在迁移到 jQuery 以获得新功能。

与此同时,我们有几个页面需要加载这两个库:

<script language="javascript" type="text/javascript"
        src="prototype-1.5.1.2.js"></script> 
<script language="javascript" type="text/javascript"  
        src="jquery-1.3.2.js"></script> 
<script language="javascript" type="text/javascript">
    $j = jQuery.noConflict();
</script> 

(请注意旧版本的原型,我们发现在逐步淘汰它时我们不想修复的升级问题)

这适用于 IE6、IE7、IE8-as-7 和 FX3,但在 Chrome 中加载它并且所有 jQuery 的东西都失败了。

加载开发者 JavaScript 控制台会显示以下错误:

Uncaught Error: NOT_SUPPORTED_ERR: DOM Exception 9 http://.../prototype-1.5.1.2.js (line 1272)
Uncaught TypeError: Object #<an Object> has no method 'ready' http://.../lib.js (line 161)
Uncaught TypeError: Object #<an Object> has no method 'slideUp' http://.../page.aspx (line 173)
... and so on - all the failures are missing jQuery methods

所以这看起来像是原型中的冲突,导致 jQuery 对象的创建失败。

特定的原型问题似乎是 Prototype.BrowserFeatures.XPath 不应该为真,因为不支持 XPath document.evaluate。

好的,现在在打开 javascript 控制台的情况下重新加载页面 - 一切正常!怎么回事?关闭控制台,重新加载,它再次失败。

只有在没有打开 javascript 控制台的情况下发生页面加载时才会发生故障 - 为什么会有任何区别?这看起来很像 Chrome 中的一个错误。

任何人都能够解释出了什么问题?为什么原型中的错误会导致 jQuery init 失败?为什么在打开控制台的情况下加载页面使其工作?

有人知道一个好的解决方法吗?(除了升级到prototype-1.6.0.3.js,它修复了这个问题,但在其他地方打破了遗留代码的负载)

4

2 回答 2

45

来自Core/jQuery.noConflict

注意:此函数必须在包含 jQuery javascript 文件之后调用,但在包含任何其他冲突库之前,以及在实际使用其他冲突库之前,以防最后包含 jQuery。可以在 jQuery.js 文件的末尾调用 noConflict 来全局禁用 $() jQuery 别名。jQuery.noConflict 返回一个对 jQuery 的引用,因此它可以用来覆盖 jQuery 对象的 $() 别名。

也许尝试将其更改为:

<script language="javascript" type="text/javascript"
  src="jquery-1.3.2.js"></script> 
<script language="javascript" type="text/javascript">
    $j = jQuery.noConflict();
</script>
<script language="javascript" type="text/javascript"
  src="prototype-1.5.1.2.js"></script>
于 2009-05-07T20:45:39.147 回答
10

我发现这个问题的根源是:

  1. Prototype 加载,并且由于 WebKit 缺少document.getElementsByClass(), Prototype (偷偷地)创建它。

  2. jQuery 初始化开始,在最顶部,它设置window.$jQuery.

  3. 在 JQuery 的初始化期间,Sizzle 引擎(在 1.3.2 中添加?)初始化。作为自省的一部分,它会检查并测试document.getElementsByClass(). 结果,它调用了 Prototype 的实现getElementsByClass(),这取决于window.$设置为 Prototype 的$,而不是 jQuery 的。

最终,这将需要在 jQuery 中修复(请参阅票证http://bugs.jquery.com/ticket/43655027)。我的快速补丁是删除 jQuery 初始化顶部的分配window.$

于 2009-12-16T15:11:16.937 回答