Corregir conflictos entre Prototype, jQuery y Bootstrap

Puede que alguna vez hayais tenido que usar conjuntamente Bootstrap, JQuery y Prototype por requerimientos del front de vuestro proyecto. En mi caso, en la aplicación en la que estoy actualizando la versión de jQuery y Bootstrap, se utilizan unas custom tags llamadas AjaxTags que hacen uso de Prototype.js y Scriptaculous.js para su correcto funcionamiento.

Cuando usamos conjuntamente estas librerías o frameworks, algunos de sus plugins pueden entrar en conflicto y provocar errores que pueden ser basante molestos y difíciles de detectar.

Tras mucho depurar Javascript pude localizar que los eventos de Prototype entraban en conflicto con Boostrap y los menús padre desaparecían al hacer clic en los items de menú o incluso al hacer click fuera del menú. Me puse a investigar un poco más y tras googlear un poco, me encontré con que había características de Bootstrap que dejaban de funcionar correctamente como:

 

  • Los componentes plegables rebotan de manera disruptiva debido a los efectos.
  • Los menús desplegables padre desaparecen al cerrar el hijo.
  • El disparador de información sobre herramientas / padre desaparece en el desenfoque.
  • El activador de popover / padre desaparece al desenfocar o alternar.
  • Las pestañas desaparecen al disparar un evento (trigger) y al hacer toggle.

Con la mayoría de estos problemas, lo que ocurre es que Prototype.js aplica display: none; al elemento padre, haciéndolo desaparecer.

Para solucionarlo, puedes insertar el siguiente código tras cargar jQuery y antes de que lo haga Prototype

 

 

jQuery.noConflict();
if (Prototype.BrowserFeatures.ElementExtensions) {
	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);
		});
	},
	pluginsToDisable = ['collapse', 'dropdown', 'modal', 'tooltip', 'popover'];
	disablePrototypeJS('show', pluginsToDisable);
	disablePrototypeJS('hide', pluginsToDisable);
}

Con el código anterior evitaremos esos errores que parecen inexplicables y que como todo en esta vida tienen una explicación.

Scroll al inicio