たまに、これは愚かな質問かもしれませんが、同じ質問をする人が他にもたくさんいることは間違いありません。私、私はちょうどそれについて100%確実にしたいと思います。 jQueryを使えば、みんな素晴らしいことがわかります。
$('document').ready(function(){});
ただし、ライブラリを使用せずに標準のJavaScriptで記述された関数を実行したい場合、そしてページが処理できるようになったらすぐに関数を起動したいとします。これに近づくための正しい方法は何ですか?
私は私ができることを知っています:
window.onload="myFunction()";
...またはbody
タグを使用できます。
<body onload="myFunction()">
...あるいは、ページの一番下ですべてを試してみることもできますが、最後のbody
タグまたはhtml
タグは次のようになります。
<script type="text/javascript">
myFunction();
</script>
JQueryの$.ready()
のように1つ以上の関数を発行する、クロスブラウザ(旧/新)準拠のメソッドとは何ですか?
ブラウザ間の互換性をすべて提供するフレームワークがない場合に行う最も簡単なことは、本体の最後にコードを呼び出すだけです。これは、すべてのイメージがロードされるのではなく、DOMの準備が整うのを待つだけなので、onload
ハンドラよりも実行が高速です。そして、これはすべてのブラウザで機能します。
<html>
<head>
</head>
<body>
Your HTML here
<script>
// self executing function here
(function() {
// your page initialization code here
// the DOM will be available here
})();
</script>
</body>
</html>
本当にそうしたくなくて、ブラウザ間の互換性が必要でwindow.onload
を待ちたくないのであれば、おそらくjQueryのようなフレームワークがその$(document).ready()
メソッドを実装する方法を見てみるべきでしょう。ブラウザの機能によってはかなり複雑です。
JQueryが何をするのか(スクリプトタグが配置されている場所ならどこでも機能する)、少しわかりました。
サポートされているなら、それは標準を試みます:
document.addEventListener('DOMContentLoaded', fn, false);
フォールバックを使って:
window.addEventListener('load', fn, false )
または古いバージョンのIEでは、次のものを使用します。
document.attachEvent("onreadystatechange", fn);
フォールバックを使って:
window.attachEvent("onload", fn);
そして、IEコードパスには、あまりよくわからない回避策がいくつかありますが、フレームとは関係があるようです。
これは、プレーンなJavaScriptで書かれたjQueryの.ready()
の完全な代替品です。
(function(funcName, baseObj) {
// The public function name defaults to window.docReady
// but you can pass in your own object and own function name and those will be used
// if you want to put them in a different namespace
funcName = funcName || "docReady";
baseObj = baseObj || window;
var readyList = [];
var readyFired = false;
var readyEventHandlersInstalled = false;
// call this when the document is ready
// this function protects itself against being called more than once
function ready() {
if (!readyFired) {
// this must be set to true before we start calling callbacks
readyFired = true;
for (var i = 0; i < readyList.length; i++) {
// if a callback here happens to add new ready handlers,
// the docReady() function will see that it already fired
// and will schedule the callback to run right after
// this event loop finishes so all handlers will still execute
// in order and no new ones will be added to the readyList
// while we are processing the list
readyList[i].fn.call(window, readyList[i].ctx);
}
// allow any closures held by these functions to free
readyList = [];
}
}
function readyStateChange() {
if ( document.readyState === "complete" ) {
ready();
}
}
// This is the one public interface
// docReady(fn, context);
// the context argument is optional - if present, it will be passed
// as an argument to the callback
baseObj[funcName] = function(callback, context) {
if (typeof callback !== "function") {
throw new TypeError("callback for docReady(fn) must be a function");
}
// if ready has already fired, then just schedule the callback
// to fire asynchronously, but right away
if (readyFired) {
setTimeout(function() {callback(context);}, 1);
return;
} else {
// add the function and context to the list
readyList.Push({fn: callback, ctx: context});
}
// if document already ready to go, schedule the ready function to run
if (document.readyState === "complete") {
setTimeout(ready, 1);
} else if (!readyEventHandlersInstalled) {
// otherwise if we don't have event handlers installed, install them
if (document.addEventListener) {
// first choice is DOMContentLoaded event
document.addEventListener("DOMContentLoaded", ready, false);
// backup is window load event
window.addEventListener("load", ready, false);
} else {
// must be IE
document.attachEvent("onreadystatechange", readyStateChange);
window.attachEvent("onload", ready);
}
readyEventHandlersInstalled = true;
}
}
})("docReady", window);
コードの最新版はGitHubの https://github.com/jfriend00/docReady で公開されています。
使用法:
// pass a function reference
docReady(fn);
// use an anonymous function
docReady(function() {
// code here
});
// pass a function reference and a context
// the context will be passed to the function as the first argument
docReady(fn, context);
// use an anonymous function with a context
docReady(function(context) {
// code here that can use the context argument that was passed to docReady
}, ctx);
これはでテストされています:
IE6 and up
Firefox 3.6 and up
Chrome 14 and up
Safari 5.1 and up
Opera 11.6 and up
Multiple iOS devices
Multiple Android devices
実用的な実装とテストベッド: http://jsfiddle.net/jfriend00/YfD3C/ /
これがどのように機能するかの概要は次のとおりです。
docReady(fn, context)
docReady(fn, context)
が呼び出されたら、readyハンドラが既に起動しているかどうかを確認してください。そうであれば、このJSのスレッドがsetTimeout(fn, 1)
で終了した直後に、新しく追加されたコールバックを起動するようにスケジュールするだけです。document.addEventListener
が存在する場合は、"DOMContentLoaded"
と"load"
の両方のイベントに.addEventListener()
を使用してイベントハンドラをインストールします。 「ロード」は安全のためのバックアップイベントであり、必要ではないはずです。document.addEventListener
が存在しない場合は、"onreadystatechange"
および"onload"
イベントに.attachEvent()
を使用してイベントハンドラをインストールします。onreadystatechange
イベントで、document.readyState === "complete"
が正しいかどうかを確認し、正しい場合はすべての準備済みハンドラーを起動する関数を呼び出します。docReady()
で登録されたハンドラは、登録された順番で起動されることが保証されています。
ドキュメントの準備が完了した後にdocReady(fn)
を呼び出すと、現在の実行スレッドがsetTimeout(fn, 1)
を使用して完了するとすぐにコールバックが実行されるようにスケジュールされます。これにより、呼び出し側のコードは、後でJSの現在のスレッドが終了して呼び出し順が保持されるとすぐに遅くなっても、後で呼び出される非同期コールバックであると常に見なすことができます。
ここで考えられるいくつかの方法をすべてのブラウザで機能する純粋なJavaScriptトリックと一緒に説明します。
// with jQuery
$(document).ready(function(){ /* ... */ });
// shorter jQuery version
$(function(){ /* ... */ });
// without jQuery (doesn't work in older IEs)
document.addEventListener('DOMContentLoaded', function(){
// your code goes here
}, false);
// and here's the trick (works everywhere)
function r(f){/in/.test(document.readyState)?setTimeout('r('+f+')',9):f()}
// use like
r(function(){
alert('DOM Ready!');
});
オリジナルの作者 で説明されているように、ここでのトリックはdocument.readyStateプロパティをチェックしていることです。それが文字列in
を含む場合(uninitialized
とloading
、最初の2つの DOM準備完了状態 5のように)、タイムアウトを設定して再度チェックします。そうでなければ、渡された関数を実行します。
そしてここに jsFiddle があります。これはすべてのブラウザで動作します。
Tutorialzine のおかげで、これを彼らの本に含めてくれました。
JQueryを使わずに Vanilla plain JavaScript を実行している場合は、(Internet Explorer 9以降)を使用する必要があります。
document.addEventListener("DOMContentLoaded", function(event) {
// Your code to run since DOM is loaded and ready
});
上記はjQueryの.ready
と同等です。
$(document).ready(function() {
console.log("Ready!");
});
どのALSOもこのようにSHORTHANDと書くことができます。どのjQueryはready /の後でも実行されます が発生します 。
$(function() {
console.log("ready!");
});
BELOW と混同しないでください(これはDOM対応ではありません)。
自己実行型の _ iife _ を使用しないでください。
Example:
(function() {
// Your page initialization code here - WRONG
// The DOM will be available here - WRONG
})();
このIIFEはあなたのDOMがロードされるのを待ちません。 (私はChromeブラウザの最新バージョンについても話しています!)
IE9、および最新のFirefoxとChromeでテストされており、IE8でもサポートされています。
document.onreadystatechange = function () {
var state = document.readyState;
if (state == 'interactive') {
init();
} else if (state == 'complete') {
initOnCompleteLoad();
}
};
例: http://jsfiddle.net/electricvisions/Jacck/
更新 - 再利用可能なバージョン
私は以下を開発しました。これは、jQueryやDomとの下位互換性がなくてもかなり単純化されたものです。おそらくさらに洗練が必要です。最新バージョンのChrome、Firefox、およびIE(10/11)でテストされており、コメントされているとおり古いブラウザでも動作するはずです。何か問題が見つかったら更新します。
window.readyHandlers = [];
window.ready = function ready(handler) {
window.readyHandlers.Push(handler);
handleState();
};
window.handleState = function handleState () {
if (['interactive', 'complete'].indexOf(document.readyState) > -1) {
while(window.readyHandlers.length > 0) {
(window.readyHandlers.shift())();
}
}
};
document.onreadystatechange = window.handleState;
使用法:
ready(function () {
// your code here
});
これはJSの非同期ロードを処理するように書かれていますが、縮小しない限り、最初にこのスクリプトを同期ロードすることをお勧めします。私はそれが開発に役立つことがわかりました。
最近のブラウザではスクリプトの非同期ロードもサポートされているため、操作性がさらに向上しています。非同期のサポートは、ページをレンダリングしながら複数のスクリプトを同時にダウンロードできることを意味します。非同期にロードされた他のスクリプトに依存している場合、または依存関係を処理するためにミニファイアまたはbrowserifyのようなものを使用している場合は、注意してください。
HubSpotの優れた人々は、ready
を含む、jQueryの優れた点を多く実現するための純粋なJavascript方法論を見つけることができるリソースを持っています
http://youmightnotneedjquery.com/#ready
function ready(fn) {
if (document.readyState != 'loading'){
fn();
} else if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', fn);
} else {
document.attachEvent('onreadystatechange', function() {
if (document.readyState != 'loading')
fn();
});
}
}
インラインの使用例
ready(function() { alert('hello'); });
あなたの方法(bodyタグを閉じる前にスクリプトを配置する)
<script>
myFunction()
</script>
</body>
</html>
古いブラウザと新しいブラウザをサポートするための信頼できる方法です。
私があなたが何を求めているのかよくわかりませんが、多分これは助けになるでしょう:
window.onload = function(){
// Code. . .
}
または
window.onload = main;
function main(){
// Code. . .
}
function ready(fn){var d=document;(d.readyState=='loading')?d.addEventListener('DOMContentLoaded',fn):fn();}
好きに使う
ready(function(){
//some code
});
(function(fn){var d=document;(d.readyState=='loading')?d.addEventListener('DOMContentLoaded',fn):fn();})(function(){
//Some Code here
//DOM is avaliable
//var h1s = document.querySelector("h1");
});
サポート:IE9 +
これは、 Ram-swaroopの "すべてのブラウザで動作する" のすべてのブラウザで動作する、クリーンアップされた、評価に使用しないバージョンです。
function onReady(yourMethod) {
var readyStateCheckInterval = setInterval(function() {
if (document && document.readyState === 'complete') { // Or 'interactive'
clearInterval(readyStateCheckInterval);
yourMethod();
}
}, 10);
}
// use like
onReady(function() { alert('hello'); } );
実行には10ミリ秒かかりますが、もっと複雑な方法はありません。
function onReady(yourMethod) {
if (document.readyState === 'complete') { // Or also compare to 'interactive'
setTimeout(yourMethod, 1); // Schedule to run immediately
}
else {
readyStateCheckInterval = setInterval(function() {
if (document.readyState === 'complete') { // Or also compare to 'interactive'
clearInterval(readyStateCheckInterval);
yourMethod();
}
}, 10);
}
}
// Use like
onReady(function() { alert('hello'); } );
// Or
onReady(functionName);
/ - もご覧くださいDOMがフレームワークなしで準備できているかどうかを確認するにはどうすればいいですか?。
document.ondomcontentready=function(){}
がうまくいくはずですが、ブラウザとの完全な互換性はありません。
あなただけのjQueryのminを使用する必要があるように思えます