Problème:
fichiers js Charge de manière asynchrone, puis vérifiez si le dom est chargé avant le rappel de chargement des fichiers est exécuté.charge javascript async, puis vérifiez DOM chargé avant d'exécuter le rappel
éditer: Nous n'utilisons pas jQuery; Nous utilisons Prototype.
modifier: a ajouté d'autres commentaires à l'exemple de code.
Hé les gars,
Je suis en train de charger tous mes fichiers js afin de manière asynchrone les empêcher de bloquer le reste de la page. Mais quand les scripts se chargent et que le callback est appelé, j'ai besoin de savoir si le DOM a été chargé ou pas, donc je sais comment structurer le callback. Voir ci-dessous:
//load asynchronously
(function(){
var e = document.createElement('script');
e.type = "text/javascript";
e.async = true;
e.src = srcstr;
// a little magic to make the callback happen
if(navigator.userAgent.indexOf("Opera")){
e.text = "initPage();";
}else if(navigator.userAgent.indexOf("MSIE")){
e.onreadystatechange = initPage;
}else{
e.innerHTML = "initPage();";
}
// attach the file to the document
document.getElementsByTagName('head')[0].appendChild(e);
})();
initPageHelper = function(){
//requires DOM be loaded
}
initPage = function(){
if(domLoaded){ // if dom is already loaded, just call the function
initPageHelper();
}else{ //if dom is not loaded, attach the function to be run when it does load
document.observe("dom:loaded", initPageHelper);
}
}
Le rappel est appelé correctement à cause de la magie dans les coulisses que vous pouvez en apprendre davantage sur de cette discussion Google: http://www.youtube.com/watch?v=52gL93S3usU&feature=related
Quelle est la meilleure méthode multi-navigateur pour demander si les DOM a déjà chargé?
EDIT
Voici la solution complète avec laquelle je suis allé.
J'ai inclus le prototype et le chargeur de script asynchrone en utilisant la méthode normale. La vie est tellement plus facile avec le prototype, donc je suis prêt à bloquer pour ce scénario.
<script type="text/javascript" src="prototype/prototype.js"></script>
<script type="text/javascript" src="asyncLoader.js"></script>
Et en fait, dans mon code, je minified les deux fichiers ci-dessus et les mettre ensemble dans un seul fichier pour réduire au minimum le temps de transfert et requêtes http.
Ensuite, je définis ce que je veux exécuter lorsque le DOM charge, puis appeler la fonction pour charger les autres scripts. De même, les demandes ci-dessus sont en fait compressées en une requête http à l'aide d'un minificateur. Ils sont laissés séparés ici pour la lisibilité. Il y a un extrait au bas de ce post montrant à quoi ressemble le code avec le minifier.
Le code pour asyncLoader.js est le suivant:
/**
* Allows you to load js files asynchronously, with a callback that can be
* called immediately after the script loads, OR after the script loads and
* after the DOM is loaded.
*
* Prototype.js must be loaded first.
*
* For best results, create a regular script tag that calls a minified, combined
* file that contains Prototype.js, and this file. Then all subsequent scripts
* should be loaded using this function.
*
*/
var onload_queue = [];
var dom_loaded = false;
function loadScriptAsync(src, callback, run_immediately) {
var script = document.createElement('script');
script.type = "text/javascript";
script.async = true;
script.src = src;
if("undefined" != typeof callback){
script.onload = function() {
if (dom_loaded || run_immediately)
callback();
else
onload_queue.push(callback);
// clean up for IE and Opera
script.onload = null;
script.onreadystatechange = null;
};
script.onreadystatechange = function() {
if (script.readyState == 'complete'){
if (dom_loaded || run_immediately)
callback();
else
onload_queue.push(callback);
// clean up for IE and Opera
script.onload = null;
script.onreadystatechange = null;
}else if(script.readyState == 'loaded'){
eval(script);
if (dom_loaded || run_immediately)
callback();
else
onload_queue.push(callback);
// clean up for IE and Opera
script.onload = null;
script.onreadystatechange = null;
}
};
}
var head = document.getElementsByTagName('head')[0];
head.appendChild(script);
}
document.observe("dom:loaded", function(){
dom_loaded = true;
var len = onload_queue.length;
for (var i = 0; i < len; i++) {
onload_queue[i]();
}
onload_queue = null;
});
j'ai ajouté la possibilité d'exécuter immédiatement un script, si vous avez des scripts qui ne reposent pas sur la page DOM étant complètement chargée.
Les demandes minified ressemblent vraiment:
<script type="text/javascript" src="/min/?b=javascript/lib&f=prototype/prototype.js,asyncLoader.js"></script>
<script type="text/javascript"> initPage = function(e){...}</script>
<script type="text/javascript">
srcstr = "/min/?f=<?=implode(',', $js_files)?>";
loadScriptAsync(srcstr, initPage);
</script>
Ils utilisent le plug-in à partir de: http://code.google.com/p/minify/
Merci pour l'aide !!
-K
J'utilise jQuery événement $ (document) .ready(). La manière la plus facile, par navigateur que je connais. – Yoni
Vous pouvez utiliser un indicateur que vous pouvez définir lorsque le DOM est chargé et vérifier ce drapeau dans votre rappel fn. – Rajat
vous pouvez marquer une réponse comme acceptée si votre problème a été résolu. – galambalazs