使用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); } }); })();
这个答案帮助我摆脱了bootstrap
和prototype
冲突的问题。
正如@ 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。