Коллапс Bootstrap конфликтует с несколькими jquery и bootstrap.js; требовать.JS
У меня есть веб-приложение (назовем его WA1), которое использует RequireJS для загрузки jQuery и Bootstrap.JS. Это приложение будет встроено в один файл (main.построенный.js) и выполняется внутри элемента страницы в другом веб-приложении (WA2).
(WA1 также может работать автономно - не будучи встроенным в WA2)
WA2 загружает jQuery и Bootstrap.js нормально, но главное.построенный.файл js также содержит jQuery и Bootstrap.JS.
Часть пользовательского интерфейса WA1 содержит элемент Bootstrap collapse. То действия сворачивания / разукрупнения инициируются атрибутами данных, помещенными в html. Если вы посмотрите на эту скрипку , элемент, который должен коллапсировать, не может коллапсировать - я думаю, потому что действие коллапса запускается дважды-один раз слушателями в Bootstrap WA2.файл js, и один раз слушателями в главном.построенный.файл js.
Я хотел бы, чтобы коллапс работал правильно, но у меня нет возможности удалить Bootstrap.js из WA2. Не имею возможность использовать RequireJS в WA2.
Есть ли способ для WA1 не загружать jQuery и Bootstrap.js с require.js, но разрешить модули, загруженные через require.js использовать jQuery и Bootstrap, которые будут загружаться нормально (без RequireJS)? Если нет, то может ли jQuery $.noconflict()
вообще помочь? Я не очень хорошо знаю, как это работает.
3 ответа:
В итоге я сделал следующее:
Перед загрузкой любых модулей require (включая jQuery) я проверяю, существует ли уже jQuery (он существует, если я работаю в WA2). Если да, то я устанавливаю
$isloaded
вtrue
.После того, как потребуется бутстрэп.js загружается, если
$isloaded
являетсяtrue
, я устанавливаю$.fn.collapse = function(){}
.Таким образом, только $.fn.функция collapse в загруженном WA2 jquery / bootstrap что-то сделает. Это выглядит немного банально, но сработало.
Скрипка: http://jsfiddle.net/wSPXP/17/
Вот один из способов сделать то, что, как я понимаю, вы хотите сделать. Операторы
console.log
просто существуют, чтобы проверить, что происходит. Если я добавлю следующий сегмент кода непосредственно перед вашимrequire
вызовом в скрипке (и после вызоваrequire.config
), то коллапсирующий элемент работает нормально:(function () { define("jquery-fake", [], function () { console.log("jquery-fake"); // Just return the already loaded jQuery. return $; }); define("bootstrap-fake", ["jquery"], function () { console.log("bootstrap-fake"); // Nothing to be done here. }); var map = {}; if ($) map.jquery = "jquery-fake"; if ($.fn.popover) map.bootstrap = "bootstrap-fake"; require.config({ map: { "*": map } }); })();
Вышесказанное не будет работать, если вы нетакже удалите jQuery из списка "внешних ресурсов". Прямо сейчас он загружается дважды , прежде чем RequireJS начнет загрузку что-нибудь.
Реквизиты:
Это должно появиться после вашего первоначального вызова
require.config
, но до того, как вы начнете загружать что-либо.JQuery и Bootstrap, загруженные для WA2, должныуже быть загружены до запуска этого кода.
Как это работает:
Он определяет, загружен ли jQuery, проверяя, что
$
установлен.Он определяет, загружается ли Bootstrap, проверяя, является ли
$.fn.popover
существует. Я не знаю санкционированного способа проверить, был ли загружен Bootstrap. Я проверил код и не увидел$.fn.bootstrap
или чего-то подобного, что предположительно было бы уникальным для Bootstrap. Он устанавливает методpopover
, так что это то, что я использую.Когда обнаруживается, что они уже присутствуют, карта для "*" заполняется так, что когда требуется
jquery
, вместо этого загружаетсяjquery-fake
, и аналогично дляbootstrap
.Два поддельных модуля-это те, которые вы видите. определено в начале кода. На самом деле они ничего не загружают.
У меня уже была подобная проблема в прошлом. Меня до сих пор раздражает, что я с ним столкнулся, но я рад, что не один такой.
Способ, которым я обошел его, был именно таким, как вы определили, чтобы использовать
$.noConflict(true)
.Вам понадобятся два сценария require config.
Для WA1 вам потребуется настроить require обычным способом. Это позволит вам запускать его как отдельное веб-приложение, независимое от WA2:
require.config({ paths: { 'jquery': '//code.jquery.com/jquery-1.11.0.min.js', //... } });
Для WA2 вам потребуется настроить требовать примерно так:
require.config({ paths: { 'jquery': 'src/jquery-no-conflict', 'jquery-src': '//code.jquery.com/jquery-1.11.0.min.js', //... } });
В jquery-no-conflict.js, мы загружаем jQuery, но возвращаем глобальный
$
к версии, загруженной WA2:define(['jquery-src'], function ($) { //unload the newly loaded version of jQuery $.noConflict(true); //return the original version return $; });
Теперь, при загрузке из WA2, ваши
Единственное, что мне не нравится в этом шаблоне, это то, что ваш HTML для WA1 теперь содержит две ссылки на jQuery, хотя глобальныйdefine
функции в WA1 будут вызывать jquery-no-conflict.js$
все равно будет указывать на первый загруженный экземпляр jQuery.Хотя я еще не пробовал, вероятно, вы можно применить аналогичный шаблон, используя Bootstrap noConflict
Пожалуйста, дайте мне знать, как у вас дела.