Подтвердить что ты не робот

Выпадающее меню Twitter Bootstrap 3 исчезает при использовании с prototype.js

У меня проблема при использовании bootstrap 3 и prototype.js вместе на веб-сайте magento.

В принципе, если вы нажмете на раскрывающееся меню (Наши продукты), а затем щелкните по фону, раскрывающееся меню (Наши продукты) исчезнет (prototype.js добавляет "display: none;" в li).

Вот демонстрация проблемы: http://ridge.mydevelopmentserver.com/contact.html

Вы можете видеть, что выпадающее меню работает так, как должно, без включения prototype.js на странице по ссылке ниже: http://ridge.mydevelopmentserver.com/

Кто-нибудь еще сталкивался с этой проблемой раньше или имел возможное решение конфликта?

EASY FIX:

Просто замените файл prototype.js Magento этим дружественным бутстрапом:

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

Вы можете увидеть изменения, сделанные в файле prototype.js, чтобы исправить ошибку bootstrap:

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

ПРИМЕЧАНИЕ. JQuery должен быть включен в ваш пурпурный цвет до prototype.js. Пример:

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

Ответ 1

Я также использовал код здесь: 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);
        }
    });
})();

Ответ 2

Поздно к партии, но нашел эту проблему 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);
}

Ответ 3

Использование селектора * с 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);
        }
    });
})();

Ответ 4

Очень поздно вечеринке: если вам не хочется запускать лишние скрипты, вы можете добавить простое переопределение CSS, чтобы предотвратить его скрытие.

.dropdown {
    display: inherit !important;
}

Как правило, использование !important в CSS рекомендуется, но я считаю, что это считается приемлемым использованием, на мой взгляд.

Ответ 5

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

Это довольно легкое решение для проверки пространства имен элемента, нажатого.

Добавить функцию проверки на prototype.js:

и после этого проверьте пространство имен до того, как элемент будет скрыт:

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

Ответ 6

Замена файла Magento prototype.js версией, поддерживаемой бутстрапом, предложенной MWD, - это ошибка, которая предотвращает сохранение настраиваемых продуктов:

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

(Запуск Magento Magento 1.7.0.2)

Решение

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

Ответ 7

Этот ответ помог мне избавиться от проблем с конфликтом bootstrap и prototype.

Как @GeekNum88 описать вопрос,

PrototypeJS добавляет методы прототипу элемента, поэтому, когда jQuery пытается для запуска метода hide() на элементе, он фактически запускает PrototypeJS hide(), который эквивалентен jQuery hide() и задает стиль элемента display:none;

Как вы предлагаете в самом вопросе, вы можете использовать bootstrap friendly prototype, иначе вы можете просто прокомментировать несколько строк в bootstrap ниже,

внутри функции Tooltip.prototype.hide

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

Ответ 8

Я понимаю, что это довольно старый пост, но ответ, о котором никто больше не упомянул, просто "модифицирует jQuery". Вам просто нужно несколько дополнительных проверок в функции запуска jQuery которая может быть найдена по строке 332.

Расширьте этот оператор 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 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 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.