奇怪的 Chrome 原型/jQuery 冲突

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/833883/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 09:53:33  来源:igfitidea点击:

Weird Chrome prototype/jQuery conflict

jquerygoogle-chromeprototypejsconflict

提问by Keith

We have an application with legacy code that relies on prototype, but we've found it to be too 'heavy' for most of the places we want to use it and and have found jQuery to be a better fit for how we work. So we're migrating to jQuery for new functionality.

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

In the meantime we have several pages that need to load both libraries:

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

<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> 

(note older version of prototype, we found issues on upgrading that we don't want to fix when we're phasing it out anyhow)

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

This works in IE6, IE7, IE8-as-7 and FX3, but load it in Chrome and all the jQuery stuff fails.

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

Loading up the developer javascript console displays the following errors:

加载开发人员 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

So this looks like a conflict in prototype that causes the creation of the jQuery object to fail.

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

The specific prototype issue appears to be Prototype.BrowserFeatures.XPath being true when it shouldn't be, as XPath document.evaluate isn't supported.

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

Ok, so now reload the page with the javascript console open - it all works!WTF? Close the console, reload and it fails again.

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

The failure only occurs when the page load occurs without the javascript console open - why would that make any difference? That looks very much like a bug in Chrome.

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

Anyone able to explain what's going wrong? Why should an error in prototype cause the jQuery init to fail? Why does loading the page with the console open make it work?

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

Anyone know a good workaround? (apart from upgrading to prototype-1.6.0.3.js, which fixes this issue but breaks a load of legacy code elsewhere)

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

回答by Jake McGraw

From Core/jQuery.noConflict:

核心/jQuery.noConflict

NOTE: This function must be called after including the jQuery javascript file, but BEFOREincluding any other conflicting library, and also before actually that other conflicting library gets used, in case jQuery is included last. noConflict can be called at the end of the jQuery.js file to globally disable the $() jQuery alias. jQuery.noConflict returns a reference to jQuery, so it can be used to override the $() alias of the jQuery object.

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

Maybe try changing it to:

也许尝试将其更改为:

<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>

回答by hblanks

I've found the root of this problem to be:

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

  1. Prototype loads, and because WebKit lacks document.getElementsByClass(), Prototype (insidously) creates it.

  2. jQuery initialization begins, and at the very top, it sets window.$to jQuery.

  3. During JQuery's initialization, the Sizzle engine (added in 1.3.2?) initializes. As part of its introspection, it checks for, and then tests the functionality of document.getElementsByClass(). As a result, it calls Prototype's impelementation of getElementsByClass(), which depends on window.$being set to Prototype's $, not jQuery's.

  1. Prototype 加载,并且因为 WebKit 缺少document.getElementsByClass(),Prototype(阴险地)创建了它。

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

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

Ultimately, this will need to be fixed in jQuery (see tickets http://bugs.jquery.com/ticket/4365and 5027). My quick patch was to remove the assignment to window.$in the top of jQuery's initialization.

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