web-dev-qa-db-fra.com

Étrange Chrome prototype / conflit de jQuery

Nous avons une application avec le code hérité qui s'appuie sur le prototype, mais nous avons trouvé qu'il était trop "lourd" pour la plupart des endroits où nous souhaitons l'utiliser et et avons trouvé que JQuery est un meilleur ajustement pour la façon dont nous travaillons. Nous migrons donc vers JQuery pour de nouvelles fonctionnalités.

En attendant, nous avons plusieurs pages qui doivent charger les deux bibliothèques:

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

(Notez la version antérieure du prototype, nous avons trouvé des problèmes sur la mise à niveau que nous ne voulons pas résoudre quand nous sommes en phase de toute façon)

Cela fonctionne dans IE6, IE7, IE8-AS-7 et FX3, mais le charger in Chrome et toutes les trucs jQuery échouent.

Chargement du développeur JavaScript Console Affiche les erreurs suivantes:

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

Cela ressemble donc à un conflit dans le prototype qui provoque l'échec de la création de l'objet JQuery.

Le problème de prototype spécifique semble être prototype.BrowserFeatures.xpath étant vrai lorsqu'il ne devrait pas être, car XPath Document.valuate n'est pas pris en charge.

OK, alors maintenant Rechargez la page avec la console JavaScript Ouvrir - Tout fonctionne! wtf? Fermez la console, rechargez et elle échoue à nouveau.

L'échec ne se produit que lorsque la charge de la page se produit sans la console JavaScript ouverte - pourquoi cela ferait-il une différence? Cela ressemble beaucoup à un bug en chrome.

Quelqu'un capable d'expliquer ce qui ne va pas? Pourquoi une erreur de prototype doit-elle causer l'échec de la jQuery init? Pourquoi charger la page avec la console ouverte le permet-il de fonctionner?

Quelqu'un sache une bonne solution? (Outre la mise à niveau vers le prototype-1.6.0.3.js, qui corrige ce problème, mais brise une charge de code hérité ailleurs)

24
Keith

De - core/jquery.noconflic :

Remarque: cette fonction doit être appelée après inclure le fichier JQuery JavaScript, mais [~ # ~] avant [~ # ~ ~] y compris toute autre bibliothèque en conflit, Et aussi avant en fait, cette autre bibliothèque conflictuelle est utilisée, dans le cas où JQuery est inclus en dernier. NOCONFLICT peut être appelé à la fin du fichier jQuery.js pour désactiver globalement l'alias $ () jquery. jquery.noconflic retourne une référence à JQuery, il peut donc être utilisé pour remplacer l'alias $ () de l'objet JQuery.

Peut-être essayer de le changer à:

<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>
44
Jake McGraw

J'ai trouvé la racine de ce problème pour être:

  1. Des charges de prototype et parce que WebKit manque document.getElementsByClass(), prototype (Indieusement) le crée.

  2. l'initialisation JQuery commence et, au sommet, il définit window.$ à jQuery.

  3. Lors de l'initialisation de JQuery, le moteur Sizzille (ajouté en 1.3.2?) Initialise. Dans le cadre de son introspection, il vérifie, puis teste la fonctionnalité de document.getElementsByClass(). En conséquence, il appelle l'impulsion de prototype de getElementsByClass(), qui dépend de window.$ Étant définie sur le prototype de $, Pas de JQuery's.

En fin de compte, cela devra être réparé dans jQuery (voir billets http://bugs.jquerery.com/ticket/4365 et 5027 ). Mon patch rapide était de supprimer l'affectation au window.$ En haut de l'initialisation de JQuery.

10
hblanks