twitter-bootstrap Twitter Bootstrap 3 下拉菜单在与prototype.js 一起使用时消失

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19139063/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 18:41:26  来源:igfitidea点击:

Twitter Bootstrap 3 dropdown menu disappears when used with prototype.js

magentotwitter-bootstrapprototypejstwitter-bootstrap-3

提问by MWD

I have an issue when using bootstrap 3 & prototype.js together on a magento website.

在 magento 网站上一起使用 bootstrap 3 和prototype.js 时遇到问题。

Basically if you click on the dropdown menu (Our Products) & then click on the background, the dropdown menu (Our Products) disappears (prototype.js adds "display: none;" to the li).

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

Here is a demo of the issue: http://ridge.mydevelopmentserver.com/contact.html

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

You can see that the dropdown menu works like it should without including prototype.js on the page at the link below: http://ridge.mydevelopmentserver.com/

您可以在以下链接的页面上看到下拉菜单的工作原理,而无需在页面上包含prototype.js:http: //ridge.mydevelopmentserver.com/

Has anyone else ran into this issue before or have a possible solution for the conflict?

有没有其他人遇到过这个问题或者有可能解决冲突的方法?

EASY FIX:

轻松修复:

Just replace Magento's prototype.js file with this bootstrap friendly one:

只需用这个引导程序友好的文件替换 Magento 的prototype.js 文件:

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

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

You can see the changes made in the prototype.js file to fix the bootstrap issue here:

您可以在prototype.js 文件中看到为修复引导程序问题所做的更改:

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

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

NOTE: JQuery must be include in your magento skin before prototype.js.. Example:

注意:JQuery 必须在prototype.js 之前包含在您的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>

回答by evgeny.myasishchev

I've also used code from here: http://kk-medienreich.at/techblog/magento-bootstrap-integration-mit-prototype-frameworkbut without a need to modify any source. Just put code below somewhere after prototype and jquery includes:

我还使用了这里的代码: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);
        }
    });
})();

回答by patrickdavey

Late to the party, but found this github issuewhich links to this informational pagewhich links to this jsfiddlewhich works really nicely. It doesn't patch on every jQuery selector and is, I think, the nicest fix by far. Copying the code here to help future peoples:

聚会迟到了,但发现这个 github 问题链接到这个信息页面该页面链接到这个 jsfiddle,它工作得非常好。它不会在每个 jQuery 选择器上打补丁,而且我认为是迄今为止最好的修复。复制此处的代码以帮助未来的人们:

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

回答by Tom Franssen

Using the * selector with jQuery is not advised. This takes every DOM object on the page and puts it in the variable. I would advice to select the elements that use a Bootstrap component specific. Solution below only uses the dropdown component:

不建议在 jQuery 中使用 * 选择器。这将获取页面上的每个 DOM 对象并将其放入变量中。我建议选择使用特定于 Bootstrap 组件的元素。下面的解决方案仅使用下拉组件:

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

回答by Chris Watts

Very late to the party: if you don't feel like having extra scripts running, you can add a simple CSS override to prevent it from getting hidden.

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

.dropdown {
    display: inherit !important;
}

Generally the use of !importantin CSS is advised against, but I think this counts as an acceptable use in my opinion.

通常!important不建议在 CSS 中使用,但我认为这在我看来是可以接受的使用。

回答by klma

see http://kk-medienreich.at/techblog/magento-bootstrap-integration-mit-prototype-framework/.

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

It's quite an easy fix to validate the namespace of the element clicked.

验证单击的元素的命名空间非常简单。

Add a validation function to prototype.js:

向prototype.js 添加验证函数:

and after that, validate the namespace before the element will be hidden:

之后,在元素将被隐藏之前验证命名空间:

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

回答by Perez Jr

Replacing Magento's prototype.js file with the bootstrap friendly version suggested by MWD is throwing an error that prevents saving configurable products:

用 MWD 建议的引导程序友好版本替换 Magento 的prototype.js 文件会引发错误,阻止保存可配置的产品:

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

(Running Magento Magento 1.7.0.2)

(运行 Magento Magento 1.7.0.2)

evgeny.myasishchev solution worked great.

evgeny.myasishchev 解决方案效果很好。

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

回答by Janith Chinthana

This answerhelped me to get rid of bootstrapand prototypeconflict issue.

这个答案让我摆脱bootstrapprototype冲突问题。

As @GeekNum88 describe the matter,

正如@GeekNum88 所描述的那样,

PrototypeJS adds methods to the Element prototype so when jQuery tries to trigger the hide()method on an element it is actually firing the PrototypeJS hide()method, which is equivalent to the jQuery hide()method and sets the style of the element to display:none;

PrototypeJS 向 Element 原型添加了方法,因此当 jQuery 尝试hide()在元素上触发该方法时,它实际上是在触发 PrototypeJShide()方法,这等效于 jQuery hide()方法并将元素的样式设置为display:none;

As you suggest in the question itself either you can use bootstrapfriendly prototypeor else you can simply comment out few lines in bootstrapas bellow,

正如您在问题本身中所建议的那样,您可以使用bootstrapfriendly prototype,否则您可以简单地注释掉几行,bootstrap如下所示,

inside the Tooltip.prototype.hidefunction

Tooltip.prototype.hide函数内部

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

回答by James Long

I realise that this is a pretty old post by now, but an answer that no-one else seems to have mentioned is simply "modify jQuery". You just need a couple of extra checks in jQuery's trigger function which can be found around line 332.

我意识到这是一个很老的帖子,但似乎没有其他人提到的答案只是“修改 jQuery”。您只需要在 jQuery 的触发器函数中进行一些额外的检查,函数可以在 332 行附近找到

Extend this ifstatement:

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

... to say this:

……这样说:

// 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" only seems to be mentioned in jQuery once so you can do a quick check for that string if you're working with a compiled (complete) jQuery library.

" #6170" 似乎只在 jQuery 中被提及过一次,因此如果您正在使用编译的(完整的)jQuery 库,您可以快速检查该字符串。