Εντάξει, αυτό μπορεί να είναι απλά μια ανόητη ερώτηση, αν και είμαι σίγουρος ότι υπάρχουν πολλοί άλλοι άνθρωποι που κάνουν την ίδια ερώτηση κατά καιρούς. Εγώ, απλά θέλω να είμαι 100% σίγουρος γι' αυτό, είτε έτσι είτε αλλιώς. Με την jQuery όλοι γνωρίζουμε το υπέροχο
$('document').ready(function(){});
Ωστόσο, ας πούμε ότι θέλω να τρέξω μια συνάρτηση που είναι γραμμένη σε τυπική JavaScript χωρίς καμία βιβλιοθήκη να την υποστηρίζει και ότι θέλω να ξεκινήσω μια συνάρτηση μόλις η σελίδα είναι έτοιμη να την χειριστεί. Ποιος'είναι ο σωστός τρόπος για να το προσεγγίσω αυτό;
Ξέρω ότι μπορώ να το κάνω:
window.onload="myFunction()";
...ή μπορώ να χρησιμοποιήσω την ετικέτα body
:
<body onload="myFunction()">
...ή μπορώ ακόμη να δοκιμάσω στο κάτω μέρος της σελίδας μετά από όλα, αλλά την ετικέτα body
ή html
στο τέλος, όπως:
<script type="text/javascript">
myFunction();
</script>
Ποια είναι μια cross-browser(παλιά/νέα)-συμβατή μέθοδος έκδοσης μιας ή περισσότερων συναρτήσεων με τρόπο όπως η $.ready()
της jQuery's?
Το απλούστερο πράγμα που μπορείτε να κάνετε ελλείψει ενός πλαισίου που να κάνει όλη τη συμβατότητα μεταξύ των προγραμμάτων περιήγησης για εσάς είναι απλά να βάλετε μια κλήση στον κώδικά σας στο τέλος του σώματος. Αυτό εκτελείται γρηγορότερα από έναν χειριστή "onload" επειδή περιμένει μόνο να είναι έτοιμο το DOM και όχι να φορτωθούν όλες οι εικόνες. Και, αυτό λειτουργεί σε κάθε πρόγραμμα περιήγησης.
<!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>
Για τα σύγχρονα προγράμματα περιήγησης (οτιδήποτε από τον IE9 και νεότερα και οποιαδήποτε έκδοση του Chrome, Firefox ή Safari), αν θέλετε να μπορείτε να υλοποιήσετε μια μέθοδο τύπου jQuery $(document).ready()
που μπορείτε να καλέσετε από οπουδήποτε (χωρίς να ανησυχείτε για το πού είναι τοποθετημένο το σενάριο κλήσης), μπορείτε απλά να χρησιμοποιήσετε κάτι σαν αυτό:
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);
}
}
Χρήση:
docReady(function() {
// DOM is loaded and ready for manipulation here
});
Αν χρειάζεστε πλήρη συμβατότητα με όλα τα προγράμματα περιήγησης (συμπεριλαμβανομένων των παλαιών εκδόσεων του IE) και δεν θέλετε να περιμένετε για το window.onload
, τότε μάλλον θα πρέπει να δείτε πώς ένα πλαίσιο όπως το jQuery υλοποιεί τη μέθοδο $(document).ready()
. Είναι αρκετά περίπλοκο, ανάλογα με τις δυνατότητες του προγράμματος περιήγησης.
Για να σας δώσουμε μια μικρή ιδέα για το τι κάνει η jQuery (η οποία θα λειτουργήσει οπουδήποτε και αν τοποθετηθεί η ετικέτα script).
Εάν υποστηρίζεται, δοκιμάζει το πρότυπο:
document.addEventListener('DOMContentLoaded', fn, false);
με αναδρομή σε:
window.addEventListener('load', fn, false )
ή για παλαιότερες εκδόσεις του IE, χρησιμοποιεί:
document.attachEvent("onreadystatechange", fn);
με αναδρομή σε:
window.attachEvent("onload", fn);
Και, υπάρχουν κάποια work-arounds στο μονοπάτι κώδικα του IE που δεν ακολουθώ ακριβώς, αλλά φαίνεται ότι έχει να κάνει με τα πλαίσια.
Εδώ είναι ένα πλήρες υποκατάστατο για την .ready()
της jQuery's γραμμένο σε απλή 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);
Η πιο πρόσφατη έκδοση του κώδικα διατίθεται δημόσια στο 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);
Αυτό έχει δοκιμαστεί σε: