Состояние гонки сценария onreadystatechange в Internet Explorer для нескольких версий jQuery
Представьте себе следующую настройку: Страница, которая имеет старую версию jQuery (скажем, 1.5.2), которую я не могу контролировать, загружает файл Javascript с моих серверов, которым также требуется jQuery, но более свежая версия. (например, 1.8.3) Теперь мой скрипт пытается сделать следующее:
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", "http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js");
script.onreadystatechange = function() { // IE
if (script.readyState === "complete" || script.readyState === "loaded") {
ready();
}
};
script.onload = function() { // other browsers
ready();
};
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script);
ready
Затем функция проверяет, $
имеет правильную версию jQuery, и если это так, он связывает этот экземпляр jQuery с другой переменной и возвращает $
в оригинальную версию JQuery, через newjQuery = window.jQuery.noConflict(true);
,
Теперь все работает отлично и прекрасно, и нет никакого (внешнего) выполнения кода между загрузкой "моей" версии jQuery и восстановлением $ в "их" версию jQuery - по крайней мере, в Chrome, Firefox и т. Д. Где этот подход не срабатывает - это Internet Explorer, который по какой-то причине обрабатывает как минимум еще одну "галочку" кода Javascript, который может работать параллельно. Это приводит к путанице в коде, который не совместим с "моей" версией jQuery, и происходит в 5 мс, где IE еще не выполнил событие ready.
Вот пример скрипки: http://jsfiddle.net/w5pPp/3/
В скрипте я проверяю текущую привязанную версию jQuery каждые 10 мс. Только в IE9 иногда есть короткий промежуток времени, когда $
ссылается на "мой" jQuery, как указано в журнале "ЭТО НЕ ДОЛЖНО БЫТЬ".
Теперь мой вопрос заключается в следующем: как лучше всего загрузить "мою" версию jQuery в ее собственную переменную, не вызывая каких-либо проблем при выполнении кода страницы за короткий промежуток времени, когда он перезаписывает "свой" jQuery перед вызовом noConflict?
1 ответ
Когда вы загружаете свою версию jQuery, попробуйте следующее:
<!-- load your jQuery version -->
<script type="text/javascript" src="http://example.com/jquery-1.9.1.js"></script>
<script type="text/javascript">
var $_mine = $.noConflict(true);
</script>
<!-- initialize their scripts -->
<script type="text/javascript" src="http://example.com/their-jquery.js"></script>
<script type="text/javascript" src="http://example.com/their-script.js"></script>
Это должно привести к тому, что у вас $_mine
доступны для использования вашей версии jQuery, не конфликтуя с другим скриптом, и его использование $
, который будет ссылаться на устаревшую версию.
Как упомянуто в комментарии выше, обратитесь к разделу Могу ли я использовать несколько версий jQuery на одной странице? для дальнейших деталей / информации / примеров.
РЕДАКТИРОВАТЬ:
Похоже, это не решит вашу проблему, основываясь на комментариях выше. В этом случае я подозреваю, что вы на самом деле видите проблему асинхронности скорости загрузки между вашими дисками. Попробуйте загрузить и вашу, и их версию jQuery одинаково, один за другим.
Другими словами:
function loadScript(variable_name, script_url) {
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", script_url);
script.onload = function() {
if (variable_name != undefined) {
window[variable_name] = jQuery.noConflict(true);
console.log("after attach: " + window[variable_name].fn.jquery);
}
};
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script);
};
loadScript('newjQuery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js');
loadScript('$', 'http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js');
//loadScript(undefined, 'http://example.com/some/dependent/script/requiring-1.5.2.js');
Вот рабочий jsFiddle, который показывает, как работает этот метод: http://jsfiddle.net/w5pPp/5/
Хитрость заключается в последовательной загрузке двух элементов и загрузке зависимостей после установки версий jQuery.