#javascript #jquery
#javascript #jquery
Вопрос:
Я работаю над javascript, который последовательно загружает список других внешних javascript.
Код, который у меня есть до сих пор:
function loadJavascript(url){
var js = document.createElement("script");
js.setAttribute("type", "text/javascript");
js.setAttribute("src", url);
if(typeof js!="undefined"){
document.getElementsByTagName("head")[0].appendChild(js)
}
}
loadJavascript("Jquery.js");
loadJavascript("second.js");
loadJavascript("third.js");
Проблема, с которой я столкнулся, заключается в том, что иногда другие файлы js загружаются до завершения загрузки файла Jquery. Это приводит к некоторым ошибкам.
Возможно ли сделать так, чтобы следующий файл JS запускался только после завершения загрузки предыдущего файла.
Заранее спасибо
Комментарии:
1. Вы могли бы проверить head.js , который делает именно это, и посмотрите, как они это реализовали. headjs.com
Ответ №1:
Конечно, есть, но для этого написаны целые библиотеки. Перестаньте изобретать велосипед и используйте то, что уже работает. Попробуйте yepnope.js или, если вы используете Modernizr, он уже доступен как Modernizr.load
Ответ №2:
loadJavascript("Jquery.js");
$(function(){
$.getScript('second.js', function(data, textStatus){
$.getScript('third.js', function(data, textStatus){
console.log("loaded");
});
});
}
Кроме того, рассмотрите возможность использования CDN Google или Microsoft для jQuery, это сэкономит вам пропускную способность, и, надеюсь, ваши посетители уже будут кэшировать его.
Комментарии:
1. да, но я также хочу second.js должны быть загружены до third.js инициируется
Ответ №3:
На самом деле, нет необходимости загружать jquery внутри функции js. Но если вы настаиваете, вы можете callback
убедиться, что другие js загружаются после jquery.
Тем не менее, я рекомендую вам загружать jquery непосредственно перед </body>
использованием $.getScript
для загрузки других .js
Ответ №4:
Вы могли бы проверить, загружен ли jQuery, что не лучший способ сделать это, но если вам действительно нужно подождать, пока загрузится jQuery, прежде чем загружать другие скрипты, вот как я бы это сделал, проверив наличие $ :
loadJavascript("Jquery.js");
T=0;
CheckIfLoaded();
function CheckIfLoaded() {
if (typeof $ == 'undefined') {
if (T <= 3000) {
alert("jQuery not loaded within 3 sec");
} else {
T=T 200;
setTimeout(CheckIfLoaded, 200);
} else {
loadJavascript("second.js");
loadJavascript("third.js");
}
}
Ответ №5:
С технической точки зрения: у браузеров есть забавный способ решить, в каком порядке выполнять / оценивать динамически загружаемый JS, поэтому, испытав ту же боль и проверив множество сообщений, библиотек, плагинов и т. Д. Я придумал это решение, автономное, маленькое, не требующее jquery, Т. Е. дружественное и т. Д. Код подробно прокомментирован:
lazyLoader = {
load: function (scripts) {
// The queue for the scripts to be loaded
lazyLoader.queue = scripts;
lazyLoader.pendingScripts = [];
// There will always be a script in the document, at least this very same script...
// ...this script will be used to identify available properties, thus assess correct way to proceed
var firstScript = document.scripts[0];
// We will loop thru the scripts on the queue
for (i = 0; i < lazyLoader.queue.length; i) {
// Evaluates if the async property is used by the browser
if ('async' in firstScript ) {
// Since src has to be defined after onreadystate change for IE, we organize all "element" steps together...
var element = document.createElement("script");
element.type = "text/javascript"
//... two more line of code than necessary but we add order and clarity
// Define async as false, thus the scripts order will be respected
element.async = false;
element.src = lazyLoader.queue[i];
document.head.appendChild(element);
}
// Somebody who hates developers invented IE, so we deal with it as follows:
// ... In IE<11 script objects (and other objects) have a property called readyState...
// ... check the script object has said property (readyState) ...
// ... if true, Bingo! We have and IE!
else if (firstScript.readyState) {
// How it works: IE will load the script even if not injected to the DOM...
// ... we create an event listener, we then inject the scripts in sequential order
// Create an script element
var element = document.createElement("script");
element.type = "text/javascript"
// Add the scripts from the queue to the pending list in order
lazyLoader.pendingScripts.push(element)
// Set an event listener for the script element
element.onreadystatechange = function() {
var pending;
// When the next script on the pending list has loaded proceed
if (lazyLoader.pendingScripts[0].readyState == "loaded" || lazyLoader.pendingScripts[0].readyState == "complete" ) {
// Remove the script we just loaded from the pending list
pending = lazyLoader.pendingScripts.shift()
// Clear the listener
element.onreadystatechange = null;
// Inject the script to the DOM, we don't use appendChild as it might break on IE
firstScript.parentNode.insertBefore(pending, firstScript);
}
}
// Once we have set the listener we set the script object's src
element.src = lazyLoader.queue[i];
}
}
}
}
Конечно, вы также можете использовать уменьшенную версию:
smallLoader={load:function(d){smallLoader.b=d;smallLoader.a=[];var b=document.scripts[0];for(i=0;i<smallLoader.b.length; i)if("async"in b){var a=document.createElement("script");a.type="text/javascript";a.async=!1;a.src=smallLoader.b[i];document.head.appendChild(a)}else b.readyStateamp;amp;(a=document.createElement("script"),a.type="text/javascript",smallLoader.a.push(a),a.onreadystatechange=function(){var c;if("loaded"==smallLoader.a[0].readyState||"complete"==smallLoader.a[0].readyState)c=smallLoader.a.shift(),
a.onreadystatechange=null,b.parentNode.insertBefore(c,b)},a.src=smallLoader.b[i])}};