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

前端 未结 8 2104
长发绾君心
长发绾君心 2020-12-07 22:28

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

Basically if you click on the dropdown menu (Our Products) & then click

相关标签:
8条回答
  • 2020-12-07 23:05

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

    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;
      },
    
    0 讨论(0)
  • 2020-12-07 23:09

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

    (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);
            }
        });
    })();
    
    0 讨论(0)
  • 2020-12-07 23:11

    This answer helped me to get rid of bootstrap and prototype conflict issue.

    As @GeekNum88 describe the matter,

    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;

    As you suggest in the question itself either you can use bootstrap friendly prototype or else you can simply comment out few lines in bootstrap as bellow,

    inside the Tooltip.prototype.hide function

    this.$element.trigger(e)
    if (e.isDefaultPrevented()) return
    
    0 讨论(0)
  • 2020-12-07 23:21

    Late to the party, but found this github issue which links to this informational page which links to this jsfiddle which 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:

    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);
    }
    
    0 讨论(0)
  • 2020-12-07 23:25

    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.

    Extend this if statement:

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

    0 讨论(0)
  • 2020-12-07 23:28

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

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

    (Running Magento Magento 1.7.0.2)

    evgeny.myasishchev solution worked great.

    (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);
            }
        });
    })();
    
    0 讨论(0)
提交回复
热议问题