web-dev-qa-db-fra.com

Quelles sont les alternatives à document.write?

Dans les tutoriels, j'ai appris à utiliser document.write. Maintenant, je comprends que cela est mal vu par beaucoup. J'ai essayé print(), mais ensuite, il l'envoie littéralement à l'imprimante.

Alors, quelles sont les alternatives que je devrais utiliser, et pourquoi je ne devrais pas utiliser document.write? W3schools et MDN utilisent document.write.

58
DarkLightA

Comme alternative recommandée à document.write, vous pouvez utiliser Manipulation DOM pour interroger et ajouter directement des éléments de nœud au DOM.

13
Darin Dimitrov

La raison pour laquelle votre code HTML a été remplacé est due à une fonction JavaScript perverse: document.write().

C'est très certainement "mauvaise forme". Cela fonctionne uniquement avec les pages Web si vous l'utilisez au chargement de la page; et si vous l'utilisez pendant l'exécution, il remplacera l'intégralité de votre document par l'entrée. Et si vous l'appliquez en tant que structure XHTML stricte, ce n'est même pas un code valide.


le problème:

document.write écrit dans le flux de documents. Appeler document.write sur un document fermé (ou chargé) appelle automatiquement document.open qui effacera le document.

- citation du MDN

document.write() a deux hommes de main, document.open() , et document.close() . Lorsque le document HTML est chargé, le document est "ouvert". Lorsque le chargement du document est terminé, le document est "fermé". Utiliser document.write() à ce stade effacera tout votre document HTML (fermé) et le remplacera par un nouveau document (ouvert). Cela signifie que votre page Web s'est effacée et a commencé à écrire une nouvelle page - à partir de zéro.

(Je crois que document.write() fait baisser les performances du navigateur (corrigez-moi si je me trompe).}


un exemple:

Cet exemple écrit la sortie dans le document HTML après que la page ait été chargée. Observez les puissances maléfiques de document.write() / effacer tout le document lorsque vous appuyez sur le bouton "Exterminer":

I am an ordinary HTML page.  I am innocent, and purely for informational purposes. Please do not <input type="button" onclick="document.write('This HTML page has been succesfully exterminated.')" value="exterminate"/>
me!


les alternatives:

  • .innerHTML C'est une excellente alternative, mais cet attribut doit être attaché à l'élément où vous voulez mettre le texte. 

Exemple: document.getElementById('output1').innerHTML = 'Some text!';

  • .createTextNode() est l’alternative recommandée par le W3C

Exemple: var para = document.createElement('p'); para.appendChild(document.createTextNode('Hello, '));

REMARQUE: il est connu que certaines performances diminuent (plus lentement que .innerHTML). Je recommande d'utiliser .innerHTML à la place.


l'exemple avec l'alternative .innerHTML:

I am an ordinary HTML page. 
I am innocent, and purely for informational purposes. 
Please do not 
<input type="button" onclick="document.getElementById('output1').innerHTML = 'There was an error exterminating this page. Please replace <code>.innerHTML</code> with <code>document.write()</code> to complete extermination.';" value="exterminate"/>
 me!
<p id="output1"></p>

65
God is good

Voici le code qui devrait remplacer document.write in-place:

document.write=function(s){
    var scripts = document.getElementsByTagName('script');
    var lastScript = scripts[scripts.length-1];
    lastScript.insertAdjacentHTML("beforebegin", s);
}
21

Laissons simplement une note ici pour dire que, bien que l'utilisation de document.write soit très désapprouvée en raison de problèmes de performances (injection synchrone de DOM et évaluation), il existe également pas d'alternative réelle 1: 1 si vous êtes en utilisant document.write pour injecter des balises de script à la demande.

Il existe de nombreux moyens de ne pas avoir à faire cela (par exemple, des chargeurs de script tels que RequireJS qui gèrent vos chaînes de dépendance), mais ils sont plus invasifs et sont donc mieux utilisés dans le site/l'application.

9
James M. Greene

La question dépend de ce que vous essayez réellement de faire.

Généralement, au lieu de faire document.write, vous pouvez utiliser someElement.innerHTML ou mieux, document.createElement avec un someElement.appendChild.

Vous pouvez également envisager d'utiliser une bibliothèque telle que jQuery et d'utiliser les fonctions de modification qu'il contient: http://api.jquery.com/category/manipulation/

7
Wolph

C’est probablement le remplacement le plus correct et direct: insertAdjacentHTML .

5
Justin Summerlin

Essayez d'utiliser getElementById () ou getElementsByName () pour accéder à un élément spécifique, puis d'utiliser la propriété innerHTML:

<html>
    <body>
        <div id="myDiv1"></div>
        <div id="myDiv2"></div>
    </body>

    <script type="text/javascript">
        var myDiv1 = document.getElementById("myDiv1");
        var myDiv2 = document.getElementById("myDiv2");

        myDiv1.innerHTML = "<b>Content of 1st DIV</b>";
        myDiv2.innerHTML = "<i>Content of second DIV element</i>";
    </script>
</html>
3
user432219

Je ne vois pas le problème avec document.write. Si vous l'utilisez avant l'événement onload, comme vous le supposez probablement, pour créer des éléments à partir de données structurées, par exemple, c'est l'outil approprié à utiliser. L'utilisation de insertAdjacentHTML ou l'ajout explicite de noeuds au DOM après la construction ne présente aucun avantage en termes de performances. Je viens de le tester de trois manières différentes avec un ancien script que j'avais l'habitude d'utiliser pour planifier les appels entrants d'un modem pour un service 24/7 sur une banque de 4 modems. 

Au moment où il est terminé, ce script crée plus de 3 000 nœuds DOM, principalement des cellules de tableau. Sur un PC âgé de 7 ans exécutant Firefox sous Vista, ce petit exercice prend moins de 2 secondes à l'aide de document.write à partir d'un fichier source local de 12 Ko et de trois fichiers GIF 1 pixels qui sont réutilisés environ 2000 fois. La page apparaît simplement comme étant complètement formée, prête à gérer des événements.

L'utilisation de insertAdjacentHTML n'est pas un substitut direct, car le navigateur ferme les balises dont le script a besoin restent ouvertes et prend deux fois plus de temps pour créer une page mutilée. Écrire toutes les pièces sur une chaîne, puis la passer à insertAdjacentHTML prend encore plus longtemps, mais au moins, vous obtenez la page telle que conçue. D'autres options (telles que la reconstruction manuelle du nœud DOM un nœud à la fois) sont tellement ridicules que je n'y vais même pas. 

Parfois, document.write est la chose à utiliser. Le fait qu’il s’agisse d’une des méthodes les plus anciennes de JavaScript n’est pas un argument contre, mais un argument en sa faveur: c’est un code hautement optimisé qui fait exactement ce qu’il était censé faire et ce depuis sa création. 

Il est agréable de savoir qu’il existe différentes méthodes de post-chargement, mais il faut bien comprendre que celles-ci sont tout à fait destinées à un but différent; à savoir modifier le DOM après sa création et son allocation de mémoire. L'utilisation de ces méthodes nécessite par nature davantage de ressources, si votre script est conçu pour écrire le code HTML à partir duquel le navigateur crée le DOM. 

Il suffit de l'écrire et de laisser le navigateur et l'interprète faire le travail. C'est ce qu'ils sont là pour.

PS: Je viens de tester l’utilisation d’un paramètre onload dans la balise body et même à ce stade, le document a toujours les fonctions open et document.write() comme prévu. En outre, il n'y a pas de différence de performance perceptible entre les différentes méthodes de la dernière version de Firefox. Bien sûr, il y a probablement une quantité de cache en cours quelque part dans la pile matériel/logiciel, mais c'est bien le problème: laissez la machine faire le travail. Cela peut toutefois faire la différence sur un smartphone bon marché. À votre santé!

2
bebopalooblog