magento - El menú desplegable de Twitter Bootstrap 3 desaparece cuando se usa con prototype.js
twitter-bootstrap prototypejs (8)
Me doy cuenta de que esta es una publicación bastante antigua, pero una respuesta que nadie más parece haber mencionado es simplemente "modificar jQuery". Solo necesita un par de controles adicionales en la función de disparo de jQuery que se puede encontrar alrededor de la línea 332 .
Extienda esta declaración if
:
// Call a native DOM method on the target with the same name name as the event.
// Don''t do default actions on window, that''s where global variables be (#6170)
if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
... para decir esto:
// Call a native DOM method on the target with the same name name as the event.
// Don''t do default actions on window, that''s where global variables be (#6170)
// Check for global Element variable (PrototypeJS) and ensure we''re not triggering one of its methods.
if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) &&
( !window.Element || !jQuery.isFunction( window.Element[ type ] ) ) ) {
" #6170
" solo parece mencionarse en jQuery una vez, por lo que puede hacer una comprobación rápida de esa cadena si está trabajando con una biblioteca jQuery compilada (completa).
Tengo un problema cuando uso bootstrap 3 y prototype.js juntos en un sitio web de magento.
Básicamente si hace clic en el menú desplegable (Nuestros productos) y luego hace clic en el fondo, el menú desplegable (Nuestros productos) desaparece (prototype.js agrega "pantalla: ninguno;" a la li).
Aquí hay una demostración del problema: http://ridge.mydevelopmentserver.com/contact.html
Puede ver que el menú desplegable funciona como debería sin incluir prototype.js en la página en el siguiente enlace: http://ridge.mydevelopmentserver.com/
¿Alguien más se ha encontrado con este problema antes o tiene una posible solución para el conflicto?
ARREGLO FÁCIL:
Simplemente reemplace el archivo prototype.js de Magento con este amigable sistema de arranque:
Puede ver los cambios realizados en el archivo prototype.js para corregir el problema de arranque aquí:
https://github.com/zikula/core/commit/079df47e7c1f536a0d9eea2993ae19768e1f0554
NOTA: JQuery debe incluirse en su máscara de magento antes de prototype.js .. Ejemplo:
<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>
Muy tarde para la fiesta: si no desea ejecutar secuencias de comandos adicionales, puede agregar una anulación CSS simple para evitar que se oculte.
.dropdown {
display: inherit !important;
}
Generalmente se desaconseja el uso de !important
en CSS, pero creo que esto cuenta como un uso aceptable en mi opinión.
No se recomienda usar el selector * con jQuery. Esto toma todos los objetos DOM en la página y los coloca en la variable. Aconsejaría seleccionar los elementos que usan un componente específico de Bootstrap. La siguiente solución solo usa el componente desplegable:
(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);
}
});
})();
Reemplazar el archivo prototype.js de Magento con la versión amigable de arranque sugerida por MWD genera un error que evita guardar productos configurables:
Uncaught TypeError: Object [object Array] has no method ''gsub'' prototype.js:5826
(Ejecutando Magento Magento 1.7.0.2)
La solución evgeny.myasishchev funcionó muy bien.
(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);
}
});
})();
También utilicé código aquí: http://kk-medienreich.at/techblog/magento-bootstrap-integration-mit-prototype-framework pero sin necesidad de modificar ninguna fuente. Simplemente coloque el código debajo en algún lugar después del prototipo y jquery incluye:
(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);
}
});
})();
Tarde en la fiesta, pero encontré este problema github que enlaza a esta página informativa que enlaza a este jsfiddle que funciona muy bien. No se aplica parche en todos los selectores de jQuery y, creo, es la mejor solución con diferencia. Copiando el código aquí para ayudar a las personas del futuro:
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);
}
ver http://kk-medienreich.at/techblog/magento-bootstrap-integration-mit-prototype-framework/ .
Es una solución bastante sencilla para validar el espacio de nombre del elemento al que se hace clic.
Agregue una función de validación a prototype.js:
y después de eso, valide el espacio de nombre antes de que el elemento se oculte:
hide: function(element) {
element = $(element);
if(!isBootstrapEvent)
{
element.style.display = ''none'';
}
return element;
},
Esta respuesta me ayudó a deshacerme de la cuestión del conflicto de bootstrap
y prototype
.
Como @ GeekNum88 describe el asunto,
PrototypeJS agrega métodos al prototipo Element, por lo que cuando jQuery intenta activar el método
hide()
en un elemento, en realidad está activando el método PrototypeJShide()
, que es equivalente al método jQueryhide()
y establece el estilo del elemento endisplay:none;
Como sugieres en la pregunta, puedes usar el prototype
bootstrap
friendly o simplemente puedes comentar algunas líneas en bootstrap
como abajo,
dentro de la función Tooltip.prototype.hide
this.$element.trigger(e)
if (e.isDefaultPrevented()) return