Question

J'ai le script suivant, où les premier et troisième document.writeline sont statiques et le second est généré :

<script language="javascript" type="text/javascript">
document.write("<script language='javascript' type='text/javascript' src='before.js'><\/sc" + "ript>");
document.write("<script language='javascript' type='text/javascript'>alert('during');<\/sc" + "ript>");
document.write("<script language='javascript' type='text/javascript' src='after.js'><\/sc" + "ript>");
</script>

Firefox et Chrome affichent avant , pendant et après , alors qu'Internet Explorer affiche d'abord pendant et uniquement puis-il afficher avant et après .

J'ai rencontré un article qui indique que je ne le suis pas. le premier à le rencontrer, mais cela ne me fait guère sentir mieux.

Est-ce que quelqu'un sait comment je peux définir l'ordre pour qu'il soit déterministe dans tous les navigateurs, ou pirater IE pour qu'il fonctionne comme tous les autres navigateurs sains?

Avertissements : le fragment de code est une reproduction très simple. Il est généré sur le serveur et le second script est la seule chose qui change. C'est un long script et la raison pour laquelle il y a deux scripts avant et après est que le navigateur les mette en cache et que la partie dynamique du code soit aussi petite que possible. Il peut également apparaître plusieurs fois dans la même page avec un code généré différent.

Était-ce utile?

La solution 2

J'ai trouvé une réponse plus à mon goût:

<script language="javascript" type="text/javascript">
document.write("<script language='javascript' type='text/javascript' src='before.js'><\/sc" + "ript>");
document.write("<script defer language='javascript' type='text/javascript'>alert('during');<\/sc" + "ript>");
document.write("<script defer language='javascript' type='text/javascript' src='after.js'><\/sc" + "ript>");
</script>

Ceci retardera le chargement de pendant et de après jusqu'à ce que le chargement de la page soit terminé.

Je pense que c'est aussi bon que possible. J'espère que quelqu'un pourra donner une meilleure réponse.

Autres conseils

Non, c'est le comportement d'Internet Explorer.

Si vous attachez des scripts de manière dynamique, IE, Firefox et Chrome les téléchargeront tous de manière asynchrone.

Firefox et Chrome attendent le retour de toutes les demandes asynchrones, puis exécutent les scripts dans l’ordre dans lequel ils sont attachés dans le DOM, mais IE exécute les scripts dans l’ordre dans lequel ils sont renvoyés.

Dans la mesure où l'alerte met moins de temps à "récupérer", qu’un fichier javascript externe, ce qui explique probablement le comportement observé.

Extrait de de Kristoffer Henriksson à propos du chargement de script asynchrone :

  

Dans ce scénario, IE et Firefox vont   télécharger les deux scripts mais Internet   Explorer les exécutera également dans le   ordre ils finissent de télécharger dans   alors que Firefox les télécharge   de manière asynchrone mais les exécute toujours   dans l'ordre où ils sont attachés dans le   DOM.

     

Dans Internet Explorer, cela signifie que votre   les scripts ne peuvent pas avoir de dépendances sur   l'un l'autre comme l'ordre d'exécution   variera selon le réseau   trafic, caches, etc.

Pensez à utiliser un chargeur Javascript. Il vous permettra de spécifier les dépendances et l’ordre d’exécution des scripts tout en chargeant vos scripts de manière asynchrone pour plus de rapidité et en lissant certaines des différences de navigateur.

Voici un bon aperçu de quelques-uns d'entre eux: JavaScript essentiel: les cinq principaux chargeurs de script .

J'ai utilisé à la fois RequireJS et LabJS. À mon avis, LabJS est un peu moins avisé.

Diapositives 25/26 de cette présentation à propos de les caractéristiques des différentes méthodes d'insertion de scripts. Cela suggère qu'IE est le seul navigateur à exécuter ces scripts dans l'ordre. Tous les autres navigateurs les exécuteront dans l'ordre dans lequel ils auront fini de se charger. Même IE ne les exécutera pas dans l’ordre si un ou plusieurs d'entre eux ont un js en ligne au lieu d'un src.

L'une des méthodes suggérées consiste à insérer un nouvel élément DOM:

var se1 = document.createElement('script');
se1.src = 'a.js';

var se2 = document.createElement('script');
se2.src = 'b.js';

var se3 = document.createElement('script');
se3.src = 'c.js';

var head = document.getElementsByTagName('head')[0]
head.appendChild(se1);
head.appendChild(se2);
head.appendChild(se3);

Pour générer la deuxième section de script générée, vous pouvez utiliser un script pour générer ce contenu et transmettre les paramètres:

se2.src = 'generateScript.php?params=' + someParam;

EDIT: Malgré ce que dit l'article cité, mes tests suggèrent que la plupart des navigateurs exécuteront vos scripts document.write dans l'ordre s'ils ont chacun un code src. Par conséquent, même si je pense que la méthode ci-dessus est préférable, vous pouvez le faire. cela aussi:

<script language="javascript" type="text/javascript">
document.write("<script type='text/javascript' src='before.js'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='during.php?params=" + params + "'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='after.js'><\/sc" + "ript>");
</script>

EDIT AGAIN (réponse aux commentaires que je fais moi-même et aux autres): Vous générez déjà le script sur votre page. Tout ce que vous faites peut être déplacé vers un autre script côté serveur qui génère le même bloc de code. Si vous avez besoin de paramètres sur votre page, transmettez-les au script dans la chaîne de requête.

Vous pouvez également utiliser cette même méthode si, comme vous le suggérez, vous générez le script en ligne plusieurs fois:

<script language="javascript" type="text/javascript">
document.write("<script type='text/javascript' src='before.js'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='during.php?params=" + params1 + "'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='during.php?params=" + params2 + "'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='during.php?params=" + params3 + "'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='after.js'><\/sc" + "ript>");
</script>

Cependant, cela commence à donner l’impression que vous vous en approchez mal. Si vous générez un grand bloc de code plusieurs fois, vous devriez probablement le remplacer par une seule fonction js et l'appel à la place avec différents paramètres ...

OK ... pendant ...

// During.js
during[fish]();

après ...

// After.js
alert("After");
fish++

HTML

<!-- some html -->
<script language="javascript" type="text/javascript">
document.write("<script language='javascript' type='text/javascript' src='before.js'></sc" + "ript>");
document.write("<script language='javascript' type='text/javascript'>during[" + fish + "] = function(){alert('During!' + fish);}</sc" + "ript>");
document.write("<script language='javascript' type='text/javascript' src='during.js'></sc" + "ript>");
document.write("<script language='javascript' type='text/javascript' src='after.js'></sc" + "ript>");
</script>
<!-- some other html -->
<script language="javascript" type="text/javascript">
document.write("<script language='javascript' type='text/javascript' src='before.js'></sc" + "ript>");
document.write("<script language='javascript' type='text/javascript'>during[" + fish + "] = function(){alert('During!' + fish);}</sc" + "ript>");
document.write("<script language='javascript' type='text/javascript' src='during.js'></sc" + "ript>");
document.write("<script language='javascript' type='text/javascript' src='after.js'></sc" + "ript>");
</script>

Je suis enclin à convenir de la façon dont cela commence à sentir, cependant. En particulier, pourquoi n’avez-vous pas pu coder le "pendant"? dans un fichier js créé dynamiquement, et insérez-le?

Notez que le script généré dynamiquement va à l'intérieur de la fonction dans le second document.write.
Testé en FF2, IE7

Vous pouvez forcer l'exécution sécurisée en définissant " onload " (ou similaire) sur les scripts et injecte le suivant dans la fonction event. Ce n’est pas anodin, mais il existe de nombreux exemples, en voici un.

http://www.phpied.com/javascript-include-ready- onload /

Je pense que des bibliothèques populaires telles que jQuery ou prototype peuvent vous aider.

Code à fournir:

<script language="javascript" type="text/javascript">
document.write("<script language='javascript' type='text/javascript'>function callGeneratedContent() { alert('during'); }<\x2Fscript>");
document.write("<script language='javascript' type='text/javascript' src='before.js'><\x2Fscript>");
document.write("<script language='javascript' type='text/javascript' src='after.js'><\x2Fscript>");
</script>

Dans before.js:

alert("Before");
callGeneratedContent();

Dans after.js:

alert("After");

Vous devez d'abord placer la ligne générée, sinon FF se plaindra car il exécute before.js avant d'afficher la définition de la fonction.

Que diriez-vous de cela:

<script>
document.write("<script src='before.js'><\/script>");
</script>

<script >
document.write("<script>alert('during');<\/script>");
</script>

<script>
document.write("<script src='after.js'><\/script>");
</script>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top