На моем веб-сайте я загружаю большинство JavaScript асинхронно с помощью RequireJs. Для моей настройки RequireJs см. Следующее:
require.config({
paths: {
'jquery': '//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery'
},
shim: {
'jquery.accordion': {
deps: ['jquery']
}
}
});
Скажем, у меня есть следующий код, определенный внутри тела, для загрузки файла асинхронно:
require(['DisplayAccordion']);
Где DisplayAccordion.js содержит следующее:
define(['jquery', 'jquery.accordion'], function($) {
$(function() {
$('.xyz').accordion();
});
});
Примечание. jquery.accordion - это просто плагин jQuery, который не поддерживает AMD и требует определения глобальной переменной jQuery.
Это отлично работает, но теперь я говорю о том, что я опускаю ссылку script на своей странице в стороннюю библиотеку. Например:
<script src="//example.com/ThirdParty.js"></script>
Если библиотека сторонних разработчиков загружает собственную версию jQuery. Теперь я получаю сообщение об ошибке:
Объект не поддерживает свойство или метод "аккордеон".
После прохождения кода я обнаружил, что он выполняется в следующем порядке:
- ThirdParty.js
- jquery.min.js - сторонняя версия
- jquery.min.js - моя версия
- jquery.accordion.js - где $указывает на мою ссылку на версию jQuery
- DisplayAccordion.js(функция обратного вызова) - где $указывает на стороннюю версию jQuery
Теперь я могу понять, почему я получаю ошибку, потому что плагин прикреплен к другому объекту. Однако я не уверен, почему это сделало бы это.
В приведенной ниже информации просто объясняется, почему использование $.noConflict(true) не будет работать.
После некоторых исследований по этому вопросу. Я изменил свою конфигурацию на:
require.config({
paths: {
'jquery': '//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery'
},
map: {
'*': { 'jquery': 'jquery-private' },
'jquery-private': { 'jquery': 'jquery' }
},
shim: {
'jquery.accordion': {
deps: ['jquery']
}
}
});
Где jquery-private.js определяется как:
define(['jquery'], function($) {
return $.noConflict(true);
});
Обратите внимание, что это было взято из http://www.requirejs.org/docs/jquery.html#noconflictmap
Теперь он выполняется в следующем порядке:
- ThirdParty.js
- jquery.min.js - сторонняя версия
- jquery-private.js(функция обратного вызова)
- jquery.min.js - моя версия
- jquery.accordion.js - где $is undefined
- DisplayAccordion.js(функция обратного вызова) - где $указывает на стороннюю версию JQuery
Как вы можете себе представить, это не сработает, так как $is undefined в файле jquery.accordion.js.
После abit дальнейшей отладки я обнаружил, что сторонняя библиотека также вызывает:
$.noConflict(true);
Думаю, я понимаю, что происходит здесь. Когда он вызывает $.noConflict(true) в сторонней библиотеке, он пытается установить глобальные переменные $и jQuery в предыдущую версию. Однако, поскольку ни одна предыдущая версия не загружена, она установлена на undefined.
Теперь, когда он вызывает jquery-private.js и возвращает $.noConflict(true), он вернет глобальную переменную jQuery, которая была установлена на undefined. Однако теперь он установит глобальную переменную jQuery в стороннюю версию библиотеки.
Итак, когда он загружает jquery.accordion $is undefined. Но когда он вызывает вызовы DisplayAccordion.js, он теперь ссылается на стороннюю версию библиотеки jQuery.
Буду признателен, если кто-нибудь может предложить исправить. Благодаря