Oke, ini mungkin pertanyaan konyol, meskipun aku'm yakin ada banyak orang lain yang menanyakan pertanyaan yang sama dari waktu ke waktu. Aku, aku hanya ingin membuat 100% yakin tentang hal itu dengan cara baik. Dengan jQuery kita semua tahu indah
$('document').ready(function(){});
Namun, let's mengatakan saya ingin menjalankan sebuah fungsi yang ditulis dalam JavaScript standar dengan tidak ada perpustakaan dukungan itu, dan yang saya ingin memulai sebuah fungsi sesegera halaman siap untuk menanganinya. Apa's cara yang tepat untuk pendekatan ini?
Aku tahu aku bisa melakukan:
window.onload="myFunction()";
...atau saya bisa menggunakan tubuh
tag:
<body onload="myFunction()">
...atau saya bisa bahkan mencoba di bagian bawah halaman setelah segala sesuatu, tapi akhirnya tubuh
atau html
tag seperti:
<script type="text/javascript">
myFunction();
</script>
Apa yang adalah cross-browser(lama/baru)-compliant metode menerbitkan satu atau lebih fungsi dalam cara seperti jQuery's $.siap()
?
Hal yang paling sederhana untuk melakukan dengan tidak adanya kerangka kerja yang melakukan semua kompatibilitas cross-browser untuk anda adalah untuk hanya menempatkan panggilan ke kode anda di akhir tubuh. Ini adalah lebih cepat untuk mengeksekusi dari sebuah onload
handler karena ini hanya menunggu untuk DOM siap, tidak untuk semua untuk memuat gambar. Dan, ini bekerja di setiap browser.
<!doctype html>
<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>
Untuk browser modern (apa pun dari IE9 dan yang lebih baru dan setiap versi dari Chrome, Firefox, atau Safari), jika anda ingin untuk dapat menerapkan jQuery seperti $(document).siap()
metode yang anda dapat menelepon dari mana saja (tanpa khawatir tentang di mana memanggil script diposisikan), anda hanya dapat menggunakan sesuatu seperti ini:
function docReady(fn) {
// see if DOM is already available
if (document.readyState === "complete" || document.readyState === "interactive") {
// call on next available tick
setTimeout(fn, 1);
} else {
document.addEventListener("DOMContentLoaded", fn);
}
}
Penggunaan:
docReady(function() {
// DOM is loaded and ready for manipulation here
});
Jika anda membutuhkan kompatibilitas cross browser penuh (termasuk versi lama IE) dan anda don't ingin menunggu jendela.onload
, maka anda mungkin harus pergi melihat bagaimana framework seperti jQuery mengimplementasikan $(document).siap()
metode. It's cukup terlibat tergantung pada kemampuan browser.
Untuk memberikan sedikit gambaran apa jQuery apa (yang akan bekerja di mana pun tag script ditempatkan).
Jika didukung, mencoba standar:
document.addEventListener('DOMContentLoaded', fn, false);
dengan mundur ke:
window.addEventListener('load', fn, false )
atau untuk versi IE, menggunakan:
document.attachEvent("onreadystatechange", fn);
dengan mundur ke:
window.attachEvent("onload", fn);
Dan, ada beberapa pekerjaan-arounds di IE jalan kode bahwa aku don't cukup ikuti, tapi sepertinya itu ada hubungannya dengan frame.
Berikut ini merupakan pengganti penuh untuk jQuery's .siap()
ditulis dalam bahasa javascript:
(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);
Versi terbaru dari kode ini dibagikan secara publik pada GitHub https://github.com/jfriend00/docReady
Penggunaan:
// 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);
Ini telah diuji pada:
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
Implementasi kerja dan test bed:
Berikut ini's ringkasan bagaimana cara kerjanya:
docReady(fn, konteks)
docReady(fn, konteks)
disebut, periksa apakah siap handler sudah dipecat. Jika demikian, hanya jadwal yang baru ditambahkan callback untuk api tepat setelah thread ini dari JS selesai dengan setTimeout(fn, 1)
.dokumen.addEventListener
ada, kemudian memasang event handler menggunakan .addEventListener()
untuk kedua "DOMContentLoaded"
dan "beban"
acara. "beban" adalah cadangan acara untuk keselamatan dan tidak harus diperlukan.dokumen.addEventListener
doesn't ada, kemudian memasang event handler menggunakan .attachEvent()
untuk "onreadystatechange"
dan "onload"
acara.onreadystatechange event, periksa untuk melihat jika
dokumen.readyState === "lengkap"` dan jika demikian, memanggil fungsi api semua siap penangan.Penangan terdaftar dengan docReady()
dijamin akan dipecat dalam urutan mereka terdaftar.
Jika anda menelepon docReady(fn)
setelah dokumen sudah siap, callback akan dijadwalkan untuk mengeksekusi secepat thread saat ini eksekusi selesai menggunakan setTimeout(fn, 1)
. Hal ini memungkinkan memanggil kode untuk selalu berasumsi mereka async callback yang akan dipanggil nanti, bahkan jika nanti sesegera saat ini benang JS selesai dan mempertahankan memanggil order.
Saya ingin menyebutkan beberapa cara yang mungkin di sini bersama-sama dengan a murni javascript trik yang bekerja di semua browser:
// 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!');
});
Trik berikut ini, seperti yang dijelaskan oleh penulis asli, adalah bahwa kita memeriksa dokumen.readyState properti. Jika ini berisi string di
(seperti dalam terinisialisasi
dan bongkar
, dua yang pertama DOM siap serikat out of 5) kita set timeout dan periksa lagi. Jika tidak, kita menjalankan berlalu fungsi.
Dan berikut's [jsFiddle][3] untuk trik yang bekerja di semua browser.
Terima kasih untuk Tutorialzine seperti ini dalam buku mereka.
Jika anda melakukan VANILLA polos JavaScript tanpa jQuery, maka anda harus menggunakan (Internet Explorer 9 atau yang lebih baru):
document.addEventListener("DOMContentLoaded", function(event) {
// Your code to run since DOM is loaded and ready
});
Di atas adalah setara dengan jQuery .siap
:
$(document).ready(function() {
console.log("Ready!");
});
Yang JUGA dapat ditulis dengan SINGKATAN seperti ini, yang jQuery akan berjalan setelah siap bahkan terjadi.
$(function() {
console.log("ready!");
});
TIDAK MENJADI BINGUNG dengan yang di BAWAH ini (yang ini tidak dimaksudkan untuk menjadi DOM siap):
JANGAN gunakan HIDUP seperti ini yang self executing:
Example:
(function() {
// Your page initialization code here - WRONG
// The DOM will be available here - WRONG
})();
Ini HIDUP TIDAK akan menunggu untuk anda DOM untuk memuat. (Saya'm bahkan berbicara tentang versi terbaru dari browser Chrome!)
Diuji di IE9, dan terbaru Firefox dan Chrome, dan juga didukung di IE8.
document.onreadystatechange = function () {
var state = document.readyState;
if (state == 'interactive') {
init();
} else if (state == 'complete') {
initOnCompleteLoad();
}
};
Contoh:
UPDATE - reusable versi
Aku hanya dikembangkan sebagai berikut. It's yang agak sederhana yang setara dengan jQuery atau Dom siap tanpa mundur kompatibilitas. Hal ini mungkin perlu penyempurnaan lebih lanjut. Diuji di versi terbaru dari Chrome, Firefox dan IE (10/11) dan harus bekerja di browser lama seperti dikomentari. I'll update jika saya menemukan masalah apapun.
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;
Penggunaan:
ready(function () {
// your code here
});
It's tertulis untuk menangani async loading JS tetapi anda mungkin ingin untuk melakukan sinkronisasi beban script ini terlebih dahulu, kecuali jika anda're minifying. I've menemukan itu berguna dalam pembangunan.
Browser Modern juga mendukung async loading script yang selanjutnya meningkatkan pengalaman. Dukungan untuk async berarti beberapa script dapat didownload secara bersamaan semua sementara masih render halaman. Just watch out ketika tergantung pada script lain dimuat secara asinkron atau menggunakan minifier atau sesuatu seperti browserify untuk menangani dependensi.
Orang-orang baik di HubSpot memiliki sumber daya di mana anda dapat menemukan murni Javascript metodologi untuk mencapai banyak jQuery kebaikan - termasuk siap
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();
});
}
}
contoh inline penggunaan:
ready(function() { alert('hello'); });
I'm tidak yakin apa yang anda're bertanya, tapi mungkin ini bisa membantu:
window.onload = function(){
// Code. . .
}
Atau:
window.onload = main;
function main(){
// Code. . .
}
function ready(fn){var d=document;(d.readyState=='loading')?d.addEventListener('DOMContentLoaded',fn):fn();}
Menggunakan seperti
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");
});
Dukungan: IE9+
Berikut ini's dibersihkan-up, non-eval-menggunakan versi Ram-swaroop's "bekerja di semua browser" berbagai-bekerja di semua browser!
function onReady(yourMethod) {
var readyStateCheckInterval = setInterval(function() {
if (document && document.readyState === 'complete') { // Or 'interactive'
clearInterval(readyStateCheckInterval);
yourMethod();
}
}, 10);
}
// use like
onReady(function() { alert('hello'); } );
Tidak menunggu tambahan 10 ms untuk menjalankan, namun, jadi di sini's cara yang lebih rumit yang seharusnya't:
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);
Lihat juga https://stackoverflow.com/questions/8100576/how-to-check-if-dom-is-ready-without-a-framework.