J'ai un problème lors de l'utilisation de bootstrap 3 & prototype.js ensemble sur un site Web magento.
Fondamentalement, si vous cliquez sur le menu déroulant (Nos produits) puis cliquez sur l'arrière-plan, le menu déroulant (Nos produits) disparaît (prototype.js ajoute "display: none;" au li).
Voici une démo du problème: http://ridge.mydevelopmentserver.com/contact.html
Vous pouvez voir que le menu déroulant fonctionne comme il se doit sans inclure prototype.js sur la page du lien ci-dessous: http://ridge.mydevelopmentserver.com/
Quelqu'un d'autre a-t-il déjà rencontré ce problème ou a-t-il une solution possible au conflit?
EASY FIX:
Remplacez simplement le fichier prototype.js de Magento par celui-ci bootstrap amical:
Vous pouvez voir les modifications apportées dans le fichier prototype.js pour résoudre le problème bootstrap ici:
https://github.com/zikula/core/commit/079df47e7c1f536a0d9eea2993ae19768e1f0554
REMARQUE: JQuery doit être inclus dans votre skin magento avant prototype.js .. Exemple:
<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="/js/prototype/prototype.js"></script>
<script type="text/javascript" src="/js/lib/ccard.js"></script>
<script type="text/javascript" src="/js/prototype/validation.js"></script>
<script type="text/javascript" src="/js/scriptaculous/builder.js"></script>
<script type="text/javascript" src="/js/scriptaculous/effects.js"></script>
<script type="text/javascript" src="/js/scriptaculous/dragdrop.js"></script>
<script type="text/javascript" src="/js/scriptaculous/controls.js"></script>
<script type="text/javascript" src="/js/scriptaculous/slider.js"></script>
<script type="text/javascript" src="/js/varien/js.js"></script>
<script type="text/javascript" src="/js/varien/form.js"></script>
<script type="text/javascript" src="/js/varien/menu.js"></script>
<script type="text/javascript" src="/js/mage/translate.js"></script>
<script type="text/javascript" src="/js/mage/cookies.js"></script>
<script type="text/javascript" src="/js/mage/captcha.js"></script>
J'ai également utilisé du code d'ici: http://kk-medienreich.at/techblog/magento-bootstrap-integration-mit-prototype-framework mais sans avoir besoin de modifier aucune source. Il suffit de mettre le code ci-dessous quelque part après que le prototype et jquery aient inclus:
(function() {
var isBootstrapEvent = false;
if (window.jQuery) {
var all = jQuery('*');
jQuery.each(['hide.bs.dropdown',
'hide.bs.collapse',
'hide.bs.modal',
'hide.bs.tooltip',
'hide.bs.popover',
'hide.bs.tab'], function(index, eventName) {
all.on(eventName, function( event ) {
isBootstrapEvent = true;
});
});
}
var originalHide = Element.hide;
Element.addMethods({
hide: function(element) {
if(isBootstrapEvent) {
isBootstrapEvent = false;
return element;
}
return originalHide(element);
}
});
})();
En retard à la fête, mais trouvé ce problème github qui renvoie à cette page d'information qui relie à ce jsfiddle qui fonctionne vraiment bien. Il ne corrige pas sur chaque sélecteur jQuery et est, je pense, de loin le meilleur correctif. Copie du code ici pour aider les futurs peuples:
jQuery.noConflict();
if (Prototype.BrowserFeatures.ElementExtensions) {
var pluginsToDisable = ['collapse', 'dropdown', 'modal', 'tooltip', 'popover'];
var disablePrototypeJS = function (method, pluginsToDisable) {
var handler = function (event) {
event.target[method] = undefined;
setTimeout(function () {
delete event.target[method];
}, 0);
};
pluginsToDisable.each(function (plugin) {
jQuery(window).on(method + '.bs.' + plugin, handler);
});
};
disablePrototypeJS('show', pluginsToDisable);
disablePrototypeJS('hide', pluginsToDisable);
}
Il n'est pas conseillé d'utiliser le sélecteur * avec jQuery. Cela prend chaque objet DOM sur la page et le place dans la variable. Je conseillerais de sélectionner les éléments qui utilisent un composant Bootstrap spécifique. La solution ci-dessous utilise uniquement le composant déroulant:
(function() {
var isBootstrapEvent = false;
if (window.jQuery) {
var all = jQuery('.dropdown');
jQuery.each(['hide.bs.dropdown'], function(index, eventName) {
all.on(eventName, function( event ) {
isBootstrapEvent = true;
});
});
}
var originalHide = Element.hide;
Element.addMethods({
hide: function(element) {
if(isBootstrapEvent) {
isBootstrapEvent = false;
return element;
}
return originalHide(element);
}
});
})();
Très tard pour la fête: si vous n'avez pas envie d'exécuter des scripts supplémentaires, vous pouvez ajouter un simple remplacement CSS pour éviter qu'il ne soit masqué.
.dropdown {
display: inherit !important;
}
Généralement, l'utilisation de !important
en CSS est déconseillé, mais je pense que cela compte comme une utilisation acceptable à mon avis.
Le remplacement du fichier prototype.js de Magento par la version bootstrap amicale suggérée par MWD génère une erreur qui empêche l'enregistrement des produits configurables:
Uncaught TypeError: Object [object Array] has no method 'gsub' prototype.js:5826
(Exécution de Magento Magento 1.7.0.2)
la solution evgeny.myasishchev a très bien fonctionné.
(function() {
var isBootstrapEvent = false;
if (window.jQuery) {
var all = jQuery('*');
jQuery.each(['hide.bs.dropdown',
'hide.bs.collapse',
'hide.bs.modal',
'hide.bs.tooltip'], function(index, eventName) {
all.on(eventName, function( event ) {
isBootstrapEvent = true;
});
});
}
var originalHide = Element.hide;
Element.addMethods({
hide: function(element) {
if(isBootstrapEvent) {
isBootstrapEvent = false;
return element;
}
return originalHide(element);
}
});
})();
voir http://kk-medienreich.at/techblog/magento-bootstrap-integration-mit-prototype-framework/ .
C'est une solution assez simple pour valider l'espace de noms de l'élément cliqué.
Ajoutez une fonction de validation à prototype.js:
et après cela, validez l'espace de noms avant que l'élément ne soit caché:
hide: function(element) {
element = $(element);
if(!isBootstrapEvent)
{
element.style.display = 'none';
}
return element;
},
Cette réponse m'a aidé à me débarrasser du problème de conflit entre bootstrap
et prototype
.
Comme @ GeekNum88 décrit la question,
PrototypeJS ajoute des méthodes au prototype Element, donc lorsque jQuery essaie de déclencher la méthode
hide()
sur un élément, il lance en fait la méthode PrototypeJShide()
, qui est équivalente à la fonction jQueryhide()
méthode et définit le style de l'élément surdisplay:none;
Comme vous le suggérez dans la question elle-même, vous pouvez utiliser bootstrap
friendly prototype
ou bien vous pouvez simplement commenter quelques lignes dans bootstrap
comme ci-dessous,
à l'intérieur de Tooltip.prototype.hide
fonction
this.$element.trigger(e)
if (e.isDefaultPrevented()) return