2009-08-25 6 views
0

J'ai une chose très intéressante avec un html ici.Weird javascript

<html> 
<head> 
<script language="Javascript"> 
    var str="me&myhtml"; 
    function delimit(){ 
     document.write(str); 
     document.write("<hr>"); 

    } 
</script> 
</head> 
<body onload="delimit()"> 
</body> 
</html> 

Vous avez vu 'me & myhtml' avec une ligne en dessous. Toutefois, si vous commentez //document.write ("<hr>"); alors vous venez de voir 'moi', ce qui est bizarre. Il est normal que javascript ne lise pas '&', mais interprète plutôt comme une commande. Cependant, si vous avez document.write() avec au moins 6 caractères, ou un 'br' ou 'hr', alors il affiche '&' tel quel.

Des idées?

+2

Vous ne devez pas utiliser document.write après l'événement body onload sauf si vous voulez vraiment remplacer tout le contenu de la page. – epascarello

Répondre

0

Cela a probablement à voir avec le fait que & est essentiellement un caractère d'échappement en HTML. Si vous voulez écrire une esperluette à la page, vous devez utiliser &amp;

+0

Non, je peux obtenir '&' sur ma page, pas de problèmes en utilisant '&'. Je voulais juste savoir pourquoi cela se passe. – rishi

9

S'il n'y a pas de balise HTML après &myhtml JavaScript ou le moteur de rendu HTML, il interprète probablement comme une entité non reconnue ou incomplète (manque une fin ;) et ne le rend pas. Si vous suivez me&myhtml avec une balise HTML, JavaScript ou le moteur de rendu HTML reconnaît que &myhtml n'est pas une entité incomplète car elle est suivie d'une balise HTML au lieu d'une ;.

Peu importe quelle balise HTML vous suivez la chaîne avec, <a> ou <p> fonctionnent aussi bien que <br>.

Le comportement n'est pas cohérent dans tous les navigateurs. IE 6, 7 & 8 et Firefox 2, 3 & 3.5 se comporter de la manière que vous décrivez, Safari pour Windows 3 & 4 ne rien rendre lorsque vous commentez la deuxième document.write() ou faire quelque chose comme document.write("abc");. Opera 9.64 & 10b3 rendre le texte correctement quel que soit le contenu de la seconde write().

Notez que l'utilisation document.write() en cas onload sans écrire correctement formaté et HTML valide (avec doctype et <html>, <head>, etc) est probablement un bug de toute façon. Notez que le problème ne se manifeste pas si vous le faites:

<html> 
<head> 
<script> 
function delimit() { 
    document.write('me&myhtml'); 
} 
</script> 
</head> 
<body> 
<script> 
delimit(); 
</script> 
</body> 
</html> 

Pour répondre à votre question, il est un bogue dans la mise en œuvre soit d'un cahier des charges, ou une partie non définie d'une spécification que chaque navigateur implémente différemment. Ce que vous faites est légèrement incorrect, le résultat de ce code légèrement incorrect n'est pas défini et il ne peut pas être invoqué pour se comporter de manière cohérente sur tous les principaux navigateurs utilisés aujourd'hui. Ce que vous faites devrait être évité.

+1

Très belle réponse – Steven

+0

Je pense que celui-ci est plus ce que la question originale demandait. Firefox, je le sais, compense les balises laissées non fermées et autres petites choses sémantiques. Lorsque le


est imprimé après la ligne, il semble enregistrer le & html comme une chaîne littérale au lieu d'essayer de l'interpréter comme une entité codée (comme dans &) – idrumgood

+0

Merci pour la bonne clarification. – rishi

1

Je voulais juste savoir pourquoi cela se produit.

Eh bien, le navigateur ne sait pas encore si votre & myhtml est une référence de l'entité que vous ne l'avez pas fini d'écrire encore, ou tout simplement le code cassé, il devra réparer.Par exemple, vous pouvez dire: (. Bien sûr, il n'y a pas de référence d'entité comme & myhtmlpotato, que vous pourriez faire allusion, mais l'analyseur ne sait pas encore)

document.write('&eac'); 
document.write('ute;'); 

Si vous laissez la analyseur sait qu'il n'y a plus de bits de référence d'entité à venir, en écrivant quelque chose qui ne pourrait pas être dans une référence d'entité, comme une balise <>, ou des espaces, il abandonnera et décidera que votre code est simplement cassé, et réparez-le.

Normalement, la fin de la page serait un endroit où cela se produirait, mais vous n'avez pas de fin de page, car le script ne fait pas ce que vous pensez qu'il fait. Au lieu d'appeler document.write() au cours du processus de chargement de la page d'origine quand il peut écrire du contenu sur votre page actuelle, vous l'appelez dans le chargement, à ce moment le document est complètement chargé et vous pouvez ' t ajouter à cela. Dans cet état, l'appel de document.write() appelle implicitement document.open(), détruisant la page en cours et en démarrant une nouvelle, à laquelle vous écrivez ensuite «my & myhtml». Cette nouvelle page que vous avez ouverte reste ouverte et n'est pas complètement chargée jusqu'à ce que vous appeliez document.close() pour lui dire que vous n'écrivez plus dessus. À ce stade, votre référence d'entité partielle sera résolue en tant que balisage incorrect et réparée.

+0

Bonne réponse. Bien sûr, la liste des références de caractères nommés est fixe et un navigateur pourrait dire qu'aucun d'entre eux ne démarre & myhtml ... donc il a déjà suffisamment d'informations pour savoir qu'il est mauvais, abandonner les caractères, émettre une esperluette et traiter myhtml comme normal texte. C'est probablement ce que fait Opera. – Alohci