それに直面してみましょう、jQuery/jQuery-uiは重いダウンロードです。
Googleは、初期レンダリングを高速化するために JavaScriptの遅延ロード を推奨しています。私のページはjQueryを使用して、ページの下部に配置されるいくつかのタブを設定します(主に初期ビューの外)。ページがレンダリングされた後までjQueryを延期したいと思います。
Googleの延期コードは、ページの読み込み後にbody onLoadイベントにフックすることでDOMにタグを追加します。
<script type="text/javascript">
// Add a script element as a child of the body
function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = "deferredfunctions.js";
document.body.appendChild(element);
}
// Check for browser support of event handling capability
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
</script>
この方法でjQueryの読み込みを延期したいのですが、試してみたところ、jQueryコードがjQueryを見つけることができませんでした(完全に予期しないことではありません)。
$(document).ready(function() {
$("#tabs").tabs();
});
したがって、jQueryがロードされるまでjQueryコードの実行を延期する方法を見つける必要があるようです。追加したタグの読み込みと解析が完了したことを検出するにはどうすればよいですか?
当然、 非同期ロード にも答えが含まれている可能性があります。
何かご意見は?
これを試してください。これは、jQuerifyブックマークレットから少し前に編集したものです。 jQueryをロードし、ロード後に処理を実行するために頻繁に使用します。もちろん、カスタマイズしたjqueryへの独自のURLでURLを置き換えることができます。
(function() {
function getScript(url,success){
var script=document.createElement('script');
script.src=url;
var head=document.getElementsByTagName('head')[0],
done=false;
script.onload=script.onreadystatechange = function(){
if ( !done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete') ) {
done=true;
success();
script.onload = script.onreadystatechange = null;
head.removeChild(script);
}
};
head.appendChild(script);
}
getScript('http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js',function(){
// YOUR CODE GOES HERE AND IS EXECUTED AFTER JQUERY LOADS
});
})();
JQueryとjQuery-UIを実際に1つのファイルに結合し、URLを使用します。本当に別々にロードしたい場合は、getScriptsをチェーンするだけです:
getScript('http://myurltojquery.js',function(){
getScript('http://myurltojqueryUI.js',function(){
//your tab code here
})
});
これは重要な主題のトップランキングの質問なので、@ valmarvと@amparsandからの以前の回答に基づいて、私自身がこれについて自分の意見を述べるために大胆にさせてください。
スクリプトを読み込むために多次元配列を使用しています。それらの間に依存関係がないものをグループ化する:
var dfLoadStatus = 0;
var dfLoadFiles = [
["http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"],
["http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/jquery-ui.min.js",
"/js/somespecial.js",
"/js/feedback-widget.js#2312195",
"/js/nohover.js"]
];
function downloadJSAtOnload() {
if (!dfLoadFiles.length) return;
var dfGroup = dfLoadFiles.shift();
dfLoadStatus = 0;
for(var i = 0; i<dfGroup.length; i++) {
dfLoadStatus++;
var element = document.createElement('script');
element.src = dfGroup[i];
element.onload = element.onreadystatechange = function() {
if ( ! this.readyState ||
this.readyState == 'complete') {
dfLoadStatus--;
if (dfLoadStatus==0) downloadJSAtOnload();
}
};
document.body.appendChild(element);
}
}
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
ロードされた後、最初のjqueryをロードし、他のスクリプトを一度にロードし続けます。ページの任意の場所に配列に追加することにより、スクリプトを簡単に追加できます。
dfLoadFiles.Push(["/js/loadbeforeA.js"]);
dfLoadFiles.Push(["/js/javascriptA.js", "/js/javascriptB.js"]);
dfLoadFiles.Push(["/js/loadafterB.js"]);
async/defer javascript loadingの現代的なアプローチ の良い説明があります。ただし、インラインスクリプトでは機能しません
<script type="text/javascript" src="/jquery/3.1.1-1/jquery.min.js" defer></script>
<script type="text/javascript" defer>
$(function () { // <- jquery is not yet initialized
...
});
</script>
非同期ロードの最も簡単な解決策は、@ nilskp-externalizeスクリプトによって提案されました。
<script type="text/javascript" src="/jquery/3.1.1-1/jquery.min.js" defer></script>
<script type="text/javascript" src="resources/js/onload.js" defer></script>
element.addEventListener("load", function () {
$('#tabs').tabs()
}, false);
やってみて.
HTMLファイルの最後にjQueryとjQuery依存コードを配置します。
編集:もう少し明確
<html>
<head></head>
<body>
<!-- Your normal content here -->
<script type="text/javascript" src="http://path/to/jquery/jquery.min.js"></script>
<script>//Put your jQuery code here</script>
</body>
</html>
このコードをasync/defered jqueryスクリプトタグの後に追加します。これは、すべての読み込みが完了したときに実行する必要があるものをすべて蓄積する一時的な関数$を定義します。関数を実行するために上書きされます。このコードでは、ドキュメント内でjQueryのonload構文をさらに変更する必要はありません。
<script defer async src="https://code.jquery.com/jquery-2.2.0.min.js">
<script>
var executeLater = [];
function $(func) {
executeLater.Push(func);
}
window.addEventListener('load', function () {
$(function () {
for (var c = 0; c < executeLater.length; c++) {
executeLater[c]();
}
});
})
</script>
....その後...
<script>
$(function() {
alert("loaded");
});
</script>
特定の状況では、jqueryがロードされたときにイベントを起動できます。
_<script type="text/javascript">
(function (window) {
window.jQueryHasLoaded = false;
document.body.addEventListener('jqueryloaded', function (e) {
console.log('jqueryloaded ' + new Date() );
}, false);
function appendScript(script) {
var tagS = document.createElement("script"),
s = document.getElementsByTagName("script")[0];
tagS.src = script.src;
s.parentNode.insertBefore(tagS, s);
if ( script.id == 'jquery' ) {
tagS.addEventListener('load', function (e) {
window.jQueryHasLoaded = true;
var jQueryLoaded = new Event('jqueryloaded');
document.body.dispatchEvent(jQueryLoaded);
}, false);
}
}
var scripts = [
{
'id': 'jquery',
'src': 'js/libs/jquery/jquery-2.0.3.min.js'
},
{
'src': 'js/myscript1.js'
},
{
'src': 'js/myscript2.js'
}
];
for (var i=0; i < scripts.length; i++) {
appendScript(scripts[i]);
}
}(window));
</script>
_
次に、依存関係を関数でラップします。
_// myscript1.js
(function(){
function initMyjQueryDependency() {
console.log('my code is executed after jquery is loaded!');
// here my code that depends on jquery
}
if ( jQueryHasLoaded === true )
initMyjQueryDependency();
else
document.body.addEventListener('jqueryloaded', initMyjQueryDependency, false);
}());
_
Jqueryが他のスクリプトの後にロードを完了すると、jqueryloadedイベントが発生したときに依存関係が実行されます。
Jqueryがすでにロードされている場合、_jQueryHasLoaded === true
_、依存関係はinitMyjQueryDependency()
で実行されます。
<!doctype html>
<html>
<head>
</head>
<body>
<p>If you click on the "Hide" button, I will disappear.</p>
<button id="hide" >Hide</button>
<button id="show" >Show</button>
<script type="text/javascript">
function loadScript(url, callback) {
var script = document.createElement("script")
script.type = "text/javascript";
if (script.readyState) { //IE
script.onreadystatechange = function() {
if (script.readyState == "loaded" ||
script.readyState == "complete") {
script.onreadystatechange = null;
callback();
}
};
} else { //Others
script.onload = function() {
callback();
};
}
script.src = url;
document.body.appendChild(script);
}
loadScript("http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js",
function() {
//YAHOO.namespace("mystuff");
$("#show").click(function() {
$("p").show();
});
$("#hide").click(function() {
$("p").hide();
});
//more...
});
</script>
</body>
</html>
私には、a)ロード時に実行したいjQueryコードをjQueryファイルの最後に追加するか、b)downloadJSAtOnload
関数に次のように追加するだけです。
<script type="text/javascript">
// Add a script element as a child of the body
function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = "deferredfunctions.js";
document.body.appendChild(element);
$("#tabs").tabs(); // <==== NOTE THIS. This should theoretically run after the
// script has been appended, though you'll have to test this
// because I don't know if the JavaScript above will wait for
// the script to load before continuing
}
// Check for browser support of event handling capability
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
</script>
アンパサンドのコードに基づいて、スクリプトが次々とロードされるように、チェーンをサポートする私のバージョンは次のとおりです。
var deferredJSFiles = ['jquery/jquery', 'file1', 'file2', 'file3'];
function downloadJSAtOnload() {
if (!deferredJSFiles.length)
return;
var deferredJSFile = deferredJSFiles.shift();
var element = document.createElement('script');
element.src = deferredJSFile.indexOf('http') == 0 ? deferredJSFile : '/js/' + deferredJSFile + '.js';
element.onload = element.onreadystatechange = function() {
if (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')
downloadJSAtOnload();
};
document.body.appendChild(element);
}
if (window.addEventListener)
window.addEventListener('load', downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent('onload', downloadJSAtOnload);
else
window.onload = downloadJSAtOnload;
Modernizr.load()はここで言及する価値があると思います-それは依存関係の読み込みを非常にうまく処理します
次のコードは、ウィンドウのロードが完了した後にスクリプトをロードする必要があります。
<html>
<head>
<script>
var jQueryLoaded = false;
function test() {
var myScript = document.createElement('script');
myScript.type = 'text/javascript';
myScript.async = true;
myScript.src = jQueryLoaded ? 'http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js' : 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/jquery-ui.min.js';
document.body.appendChild(myScript);
if(!jQueryLoaded){
alert('jquery was loaded');
jQueryLoaded = true;
test();
} else {
alert('jqueryui was loaded');
}
}
if (window.addEventListener){
alert('window.addEventListener');
window.addEventListener("load", test, false);
} else if (window.attachEvent){
alert('window.attachEvent');
window.attachEvent("onload", test);
} else{
alert('window.onload');
window.onload = test;
}
</script>
</head>
<body>
<p>Placeholder text goes here</p>
</body>
</html>
Chrome、FF、IE9で働いていた-それが役立つかどうか教えてください
jQuery.holdReady()
を見てください
「jQueryのreadyイベントの実行を保留または解放します。」 (jQuery 1.6以降)
必要なのは<script defer>
: http://www.w3schools.com/tags/att_script_defer.asp