使用prototype.js时,Twitter Bootstrap 3下拉菜单消失

在magento网站上使用bootstrap 3&prototype.js时,我遇到了一个问题。

基本上,如果你点击下拉菜单(我们的产品),然后点击背景,下拉菜单(我们的产品)消失(prototype.js添加“display:none;”到li)。

这是一个问题的演示: http : //ridge.mydevelopmentserver.com/contact.html

您可以看到,下拉菜单的工作方式应该不会在下面的链接中包含prototype.js: http : //ridge.mydevelopmentserver.com/

有没有其他人遇到这个问题之前,或有冲突的可能的解决办法?

容易修正:

只要用这个引导友好的replaceMagento的prototype.js文件:

https://raw.github.com/zikula/core/079df47e7c1f536a0d9eea2993ae19768e1f0554/src/javascript/ajax/original_uncompressed/prototype.js

您可以在prototype.js文件中看到修改bootstrap问题的更改:

https://github.com/zikula/core/commit/079df47e7c1f536a0d9eea2993ae19768e1f0554

注意:在prototype.js之前,jQuery必须包含在你的magento皮肤中。例子:

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

我也使用了这里的代码: http : //kk-medienreich.at/techblog/magento-bootstrap-integration-mit-prototype-framework,但不需要修改任何源代码。 只要将代码放在原型和jquery后面的某个地方就可以了:

 (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); } }); })(); 

晚了,但发现这个链接到这个信息页面链接到这个jsfiddle 这个github问题很好地工作。 它不会在每个jQueryselect器上打补丁,我认为这是目前为止最好的解决scheme。 在这里复制代码来帮助未来的人们:

 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); } 

不build议在jQuery中使用*select器。 这将获取页面上的每个DOM对象,并将其放入variables中。 我会build议select使用Bootstrap组件的元素。 下面的解决scheme只使用下拉组件:

 (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); } }); })(); 

晚会很晚:如果你不想让额外的脚本运行,你可以添加一个简单的CSS覆盖,以防止隐藏。

 .dropdown { display: inherit !important; } 

一般来说,在CSS中使用!important是不利的,但我认为这在我看来是可以接受的。

请参阅http://kk-medienreich.at/techblog/magento-bootstrap-integration-mit-prototype-framework/

validation被单击的元素的名称空间是一个相当简单的修复。

为prototype.js添加一个validation函数:

之后,validation元素将被隐藏之前的命名空间:

  hide: function(element) { element = $(element); if(!isBootstrapEvent) { element.style.display = 'none'; } return element; }, 

用MWDbuild议的引导友好版本replaceMagento的prototype.js文件会抛出一个错误,防止保存可configuration的产品:

 Uncaught TypeError: Object [object Array] has no method 'gsub' prototype.js:5826 

(运行Magento Magento 1.7.0.2)

evgeny.myasishchev解决scheme效果很好。

 (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); } }); })(); 

这个答案帮助我摆脱了bootstrapprototype冲突的问题。

正如@ GeekNum88所描述的那样,

PrototypeJS为Element原型添加了方法,所以当jQuery试图触发元素的hide()方法时,它实际上触发了PrototypeJS的hide()方法,这相当于jQuery的hide()方法,并将元素的样式设置为display:none;

正如你在问题本身中所build议的,你可以使用bootstrap友好的prototype ,否则你可以简单地在bootstrap注释掉几行,

Tooltip.prototype.hide函数内部

 this.$element.trigger(e) if (e.isDefaultPrevented()) return 

我意识到,这是一个相当古老的职位,但没有人似乎提到的答案只是“修改jQuery”。 您只需要在第332行左右的 jQuery触发器函数中多做一些额外的检查。

扩展这个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 ) ) { 

…这样说:

 // 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 ”似乎只在jQuery中提到过,所以如果您正在使用已编译(完整)jQuery库,则可以快速检查该string。