[解決済み] 非同期でスクリプトを読み込む
質問
私はいくつかのプラグイン、カスタムウィジェット、JQueryからの他のライブラリを使っています。その結果、いくつかの.jsと.cssファイルがあります。読み込みに時間がかかるので、私のサイトのローダーを作成する必要があります。すべてのファイルをインポートする前にローダーを表示することができれば、それは素晴らしいでしょう。
<script type="text/javascript" src="js/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="js/myFunctions.js"></script>
<link type="text/css" href="css/main.css" rel="stylesheet" />
...
....
etc
JavaScriptライブラリを非同期でインポートするためのチュートリアルをいくつか見つけました。
(function () {
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = 'js/jquery-ui-1.8.16.custom.min.js';
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
})();
私はすべての私のファイルのための同じ事をするとき何らかの理由でページが動作しません。私は問題がどこにあるか見つけることを試みるために長い間試してきましたが、私はそれを見つけることができません。最初は、いくつかのjavascript関数が他の関数に依存しているからだろうと思った。しかし、私は1つが完了したときにタイムアウト機能を使用して正しい順序でそれらをロードし、私は次のページに進み、ページはまだ奇妙な動作をする。
とにかく
私が考えていることは、次のとおりです... 私はブラウザがキャッシュを持っていると信じています、それは最初のページをロードするのに長い時間がかかり、次の時間は速い理由です。ajaxがこれらのファイルをすべてロードし終わると、私が使う予定のページにリダイレクトします。そのページを使うとき、ファイルはすでにブラウザのキャッシュに含まれているはずなので、ロードに長くはかからないはずです。私はローダーを表示し、完了したときにページをリダイレクトするだけです...
このアイデアは良い代替案でしょうか?それとも、非同期メソッドの実装に挑戦し続けるべきでしょうか?
EDIT
非同期で読み込む方法は、こんな感じです。
importScripts();
function importScripts()
{
//import: jquery-ui-1.8.16.custom.min.js
getContent("js/jquery-1.6.2.min.js",function (code) {
var s = document.createElement('script');
s.type = 'text/javascript';
//s.async = true;
s.innerHTML=code;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
setTimeout(insertNext1,1);
});
//import: jquery-ui-1.8.16.custom.min.js
function insertNext1()
{
getContent("js/jquery-ui-1.8.16.custom.min.js",function (code) {
var s = document.createElement('script');
s.type = 'text/javascript';
s.innerHTML=code;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
setTimeout(insertNext2,1);
});
}
//import: jquery-ui-1.8.16.custom.css
function insertNext2()
{
getContent("css/custom-theme/jquery-ui-1.8.16.custom.css",function (code) {
var s = document.createElement('link');
s.type = 'text/css';
s.rel ="stylesheet";
s.innerHTML=code;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
setTimeout(insertNext3,1);
});
}
//import: main.css
function insertNext3()
{
getContent("css/main.css",function (code) {
var s = document.createElement('link');
s.type = 'text/css';
s.rel ="stylesheet";
s.innerHTML=code;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
setTimeout(insertNext4,1);
});
}
//import: jquery.imgpreload.min.js
function insertNext4()
{
getContent("js/farinspace/jquery.imgpreload.min.js",function (code) {
var s = document.createElement('script');
s.type = 'text/javascript';
s.innerHTML=code;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
setTimeout(insertNext5,1);
});
}
//import: marquee.js
function insertNext5()
{
getContent("js/marquee.js",function (code) {
var s = document.createElement('script');
s.type = 'text/javascript';
s.innerHTML=code;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
setTimeout(insertNext6,1);
});
}
//import: marquee.css
function insertNext6()
{
getContent("css/marquee.css",function (code) {
var s = document.createElement('link');
s.type = 'text/css';
s.rel ="stylesheet";
s.innerHTML=code;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
setTimeout(insertNext,1);
});
}
function insertNext()
{
setTimeout(pageReadyMan,10);
}
}
// get the content of url and pass that content to specified function
function getContent( url, callBackFunction )
{
// attempt to create the XMLHttpRequest and make the request
try
{
var asyncRequest; // variable to hold XMLHttpRequest object
asyncRequest = new XMLHttpRequest(); // create request object
// register event handler
asyncRequest.onreadystatechange = function(){
stateChange(asyncRequest, callBackFunction);
}
asyncRequest.open( 'GET', url, true ); // prepare the request
asyncRequest.send( null ); // send the request
} // end try
catch ( exception )
{
alert( 'Request failed.' );
} // end catch
} // end function getContent
// call function whith content when ready
function stateChange(asyncRequest, callBackFunction)
{
if ( asyncRequest.readyState == 4 && asyncRequest.status == 200 )
{
callBackFunction(asyncRequest.responseText);
} // end if
} // end function stateChange
そして、奇妙なことに、すべてのスタイルが動作し、すべてのjavascriptの関数があります。
どのように解決するのですか?
非同期ロードのためのいくつかの解決策。
//this function will work cross-browser for loading scripts asynchronously
function loadScript(src, callback)
{
var s,
r,
t;
r = false;
s = document.createElement('script');
s.type = 'text/javascript';
s.src = src;
s.onload = s.onreadystatechange = function() {
//console.log( this.readyState ); //uncomment this line to see which ready states are called.
if ( !r && (!this.readyState || this.readyState == 'complete') )
{
r = true;
callback();
}
};
t = document.getElementsByTagName('script')[0];
t.parentNode.insertBefore(s, t);
}
すでにjQueryを搭載している場合はそのまま使用します。
$.getScript(url, successCallback)
*
さらに、ドキュメントの読み込みが完了する前にスクリプトが読み込まれたり実行されたりする可能性があります。
document.ready
を待つ必要があるということです。
コードを見ないと、あなたの問題が何であるかを具体的に説明することはできません。
最も簡単な解決策は、ページの下部にあるすべてのスクリプトをインラインで維持することです。また、必要な各スクリプトを非同期に読み込まなければならないという問題も回避できます。
常に使用されるわけではないが、ある種の大きなスクリプトを必要とする特に派手なインタラクションがある場合、必要になるまでその特定のスクリプトをロードしないようにすると便利です(レイジーローディング)。
*
で読み込まれるスクリプト
$.getScript
でロードされたスクリプトは、おそらくキャッシュされないでしょう。
のような現代的な機能を使える人にとっては、このような
Promise
オブジェクトを使用すると
loadScript
関数が大幅に簡素化されました。
function loadScript(src) {
return new Promise(function (resolve, reject) {
var s;
s = document.createElement('script');
s.src = src;
s.onload = resolve;
s.onerror = reject;
document.head.appendChild(s);
});
}
このバージョンは、もう
callback
引数は受け付けないことに注意してください。以前は
loadScript(src, callback)
であったものが
loadScript(src).then(callback)
.
これには、失敗を検出して処理することができるという利点があります。例えば、...
loadScript(cdnSource)
.catch(loadScript.bind(null, localSource))
.then(successCallback, failureCallback);
...そして、CDNの停止を優雅に扱うことができます。
関連
-
親子コンポーネント通信を解決する3つのVueスロット
-
fetch ネットワークリクエストラッパーの説明例
-
vue for 登録ページ効果 vue for sms 認証コードログイン
-
JavaScriptの配列共通メソッド解説
-
[解決済み】SyntaxError: JSONの位置1に予期しないトークンoがある。
-
[解決済み】ローカルファイルを開くことができません - Chrome: ローカルリソースの読み込みが許可されていない
-
[解決済み】React-Redux: アクションはプレーンオブジェクトでなければならない。非同期アクションにはカスタムミドルウェアを使用する
-
[解決済み] CSSは常にJavascriptより優先されるべきか?
-
[解決済み] ページロード後にJavaScriptを実行させるには?
-
[解決済み】5秒ごとにページを再読み込みするには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
JSアレイループと効率解析の比較
-
vueが定義するプライベートフィルタと基本的な使い方
-
Vueのイベント処理とイベントモディファイアの解説
-
Vueの一般的な組み込みディレクティブの説明
-
[解決済み] Error : 未定義のプロパティ 'map' を読み取ることができません。
-
[解決済み] 配列の結合時に未定義のプロパティ 'push' を読み込むことができない
-
[解決済み】Node.js Error: Cannot find module express
-
JSクリックイベント - Uncaught TypeError: プロパティ 'onclick' に null を設定できません。
-
[解決済み] 私のJavaScriptコードは "No 'Access-Control-Allow-Origin' header is present on requested resource "というエラーを受け取りますが、Postmanはそうならないのはなぜですか?
-
[解決済み] How to append <script></script> in JavaScript? [duplicate]