奇怪的Chrome原型/ jQuery冲突

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

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

   $j = jQuery.noConflict();  

(注意原型的旧版本,我们发现升级时出现的问题,无论如何我们都不想修复它们)

这适用于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 # has no method 'ready' http://.../lib.js (line 161) Uncaught TypeError: 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控制台 – 一切正常! WTF? 关闭控制台,重新加载,然后再次失败。

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

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

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

来自Core / jQuery.noConflict :

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

也许尝试将其更改为:

    

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

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

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

  3. 在JQuery初始化期间,Sizzle引擎(在1.3.2中添加?)初始化。 作为其内省的一部分,它检查,然后测试document.getElementsByClass()的function。 因此,它调用了Prototype对getElementsByClass()的强制执行,这取决于window.$被设置为Prototype的$ ,而不是jQuery。

最终,这需要在jQuery中修复(参见门票http://bugs.jquery.com/ticket/4365和5027 )。 我的快速补丁是在jQuery初始化的顶部删除window.$的赋值。