56 votes

Quand le navigateur exécute-t-il Javascript? Comment le curseur d'exécution se déplace-t-il?

Je me demandais s'il y a des ressources disponibles qui décrivent comment un navigateur curseur exécute le Javascript.

Je sais qu'il charge et exécute des balises lorsque le chargement d'une page, et que vous pouvez attacher les fonctions de divers événements de fenêtre, mais là où les choses deviennent floues, c'est quand, par exemple, j'ai récupérer une distance de page via AJAX et mettre son contenu dans un div.

Si cette distance page a pour charger les bibliothèques de scripts tels que <script src="anotherscript.js" />, quand est-ce "anotherscript.js" en cours de chargement et son contenu sont-ils exécutés?

Qu'advient-il si j'ai inclus "anotherscript.js" sur ma page, et puis j'ai la charge, la distance le contenu qui a un double inclure ce script? Est-il remplacer celui d'origine? Que faire si l'original "anotherscript.js" a un var en elle dont la valeur que j'ai modifié, puis-je recharger ce fichier... dois-je perdre de la valeur d'origine ou est la deuxième inclusion de ce script ignoré?

Si j'ai la charge, la procédure Javascript via AJAX, quand est-il exécuté? Immédiatement après, je n' mydiv.innerHTML(remoteContent)? Ou est-il exécuté avant que?

54voto

T.J. Crowder Points 285826

La réponse varie selon l'endroit où la balise script est et comment vous l'avez ajouté:

  1. Les balises de Script en ligne avec votre balisage sont exécutées de manière synchrone avec le navigateur traitement de balisage (à l'exception, voir #2), et donc si -- par exemple -- ces balises de référence à des fichiers externes, ils ont tendance à ralentir le traitement de la page. (C'est pour le navigateur peut manipuler document.write des déclarations, qui changent le balisage ils les traitent.)

  2. Les balises de Script avec l' defer attribut peut, sur certains navigateurs, de ne pas être exécutée jusqu'à ce que après le DOM a été entièrement rendue. Naturellement, ce ne peut pas utiliser document.write. (De la même manière il y a un async attribut qui rend le script asynchrone, mais je ne sais pas beaucoup sur le sujet ou de la façon dont il est pris en charge; les détails.)

  3. Les balises de Script dans le contenu que vous attribuez à des éléments après DOM load (via innerHTML et similaires) ne sont pas exécutées à tout, sauf votre utilisation d'une librairie comme jQuery ou Prototype pour le faire pour vous. (Avec une seule exception, l'a souligné Andy E: Sur IE, s'ils ont un defer d'attribut, il va les exécuter. Ne fonctionne pas dans les autres navigateurs.)

  4. Si vous ajoutez un réel script élément du document par l'intermédiaire d' Element#appendChild, le navigateur commence à télécharger le script et l'exécuter dès que le téléchargement est terminé. Les Scripts ajoutés de cette manière ne sont pas exécutées de manière synchrone ou nécessairement dans l'ordre. D'abord l'ajout d'un <script type="text/javascript" src="MyFct.js"></script>, et en ajoutant <script type="text/javascript">myFunction();</script> peut bien exécuter la ligne (seconde) avant la distance (premier). Si cela se produit et MyFct.js déclare myFunction(), il ne sera pas définie lorsque nous essayons de l'utiliser avec le script en ligne. Si vous avez besoin de les choses dans l'ordre, vous pouvez dire quand un script à distance a été chargé en regardant l' load et readyStateChange événements sur l' script élément que vous ajoutez (load est le cas sur la plupart des navigateurs, readyStateChange sur certaines versions d'IE, et certains navigateurs ne les deux, donc, vous avez à gérer plusieurs notifications pour le même script).

  5. Script à l'intérieur de gestionnaires d'événements sur les attributs (<a href='#' onclick='myNiftyJavaScript();'>) plutôt que dans une balise script est exécuté lorsque l'événement se produit.


Je travaillais à mon Vrai Travail, et soudain mon cerveau postérieur a dit: "Vous savez, vous avez été dit qu'ils ne seront pas exécutées si vous les affectez innerHTML, mais avez-vous vérifié personnellement?" Et je n'avais pas, donc j'ai fait, FWIW:

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Script Test Page</title>
<style type='text/css'>
body {
    font-family: sans-serif;
}
</style>
<script type='text/javascript'>
function addScript()
{
    var str, div;

    div = document.getElementById('target');
    str = "Content added<" + "script type='text/javascript'>alert('hi there')<" + "/" + "script>";
    alert("About to add:" + str);
    div.innerHTML = str;
    alert("Done adding script");
}
</script>
</head>
<body><div>
<input type='button' value='Go' onclick='addScript();'>
<div id='target'></div>
</div></body>
</html>

L'alerte à partir du script ne s'affiche pas sur IE7, FF3.6, ou Chrome4 (je n'ai pas pris la peine de vérifier les autres, je suis censé être au travail :-) ). Alors que si vous ajouter des éléments comme indiqué ici, le script est exécuté.

3voto

Pointy Points 172438

Si vous avez des trucs à un bloc de code HTML contenant des balises script dans votre DOM "innerHTML", les balises de script ne sera pas exécutée du tout. Lorsque vous chargez des trucs avec quelque chose comme jQuery, le code dans la bibliothèque explicitement poignées de trouver et d'exécuter les scripts.

Ce n'est pas exacts, mais vous pouvez vous pensez du traitement de la <script> balise comme si la totalité du contenu de la balise (c'est à dire, le corps d'un script) ont été exécutées avec eval(). Si le script déclare global (de la fenêtre) des variables, alors les valeurs anciennes sont écrasées.

Des balises de Script sont traitées dans l'ordre dans lequel elles apparaissent. Bien sûr, le code à l'intérieur des blocs de script peuvent être configurés de manière à ce qu'il fait lors de la première exécution est de différer la réelle traitement jusqu'à ce que plus tard. Beaucoup de jQuery setup/code d'initialisation va le faire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X