web-dev-qa-db-fra.com

Quelle est la bonne façon d'écrire du HTML en utilisant Javascript?

Je vois dans certains articles que les gens désapprouvent l'utilisation de document.write() en javascript lors de l'écriture de code HTML dynamique.

Pourquoi est-ce? et quelle est la manière correcte?

63
Gary Willoughby

document.write() ne fonctionnera que pendant l'analyse initiale de la page et la création du DOM. Une fois que le navigateur atteint la balise de fermeture </body> Et que le DOM est prêt, vous ne pouvez plus utiliser document.write().

Je ne dirais pas que l'utilisation de document.write() est correcte ou incorrecte, cela dépend juste de votre situation. Dans certains cas, il vous suffit d'avoir document.write() pour accomplir la tâche. Regardez comment Google Analytics est injecté dans la plupart des sites Web.

Une fois DOM prêt, vous avez deux façons d'insérer du HTML dynamique (en supposant que nous allons insérer du nouveau HTML dans <div id="node-id"></div>):

  1. Utilisation de innerHTML sur un nœud:

    var node = document.getElementById('node-id');
    node.innerHTML('<p>some dynamic html</p>');
    
  2. Utilisation des méthodes DOM:

    var node = document.getElementById('node-id');
    var newNode = document.createElement('p');
    newNode.appendChild(document.createTextNode('some dynamic html'));
    node.appendChild(newNode);
    

L'utilisation des méthodes de l'API DOM pourrait être la façon la plus pure de faire des choses, mais innerHTML s'est avéré beaucoup plus rapide et est utilisé sous le capot dans les bibliothèques JavaScript telles que jQuery.

Remarque: Le <script> Devra être à l'intérieur de votre balise <body> Pour que cela fonctionne.

45
Ricky

document.write() ne fonctionne pas avec XHTML. Il est exécuté après le chargement de la page est terminé et ne fait rien d'autre que d'écrire une chaîne de HTML.

Étant donné que la représentation HTML réelle en mémoire est le DOM, la meilleure façon de mettre à jour une page donnée est de manipuler directement le DOM.

La façon dont vous vous y prendriez serait de créer par programmation vos nœuds, puis de les attacher à un emplacement existant dans le DOM. Pour [fins d'un exemple artificiel], en supposant que j'ai un élément div conservant un attribut ID de "header", alors je pourrais introduire du texte dynamique en procédant comme suit:

// create my text
var sHeader = document.createTextNode('Hello world!');

// create an element for the text and append it
var spanHeader = document.createElement('span');
spanHeader.appendChild(sHeader);

// grab a reference to the div header
var divHeader = document.getElementById('header');

// append the new element to the header
divHeader.appendChild(spanHeader);
27
Tom

Peut-être une bonne idée est d'utiliser jQuery dans ce cas. Il fournit des fonctionnalités pratiques et vous pouvez faire des choses comme ceci:

$('div').html('<b>Test</b>');

Jetez un œil à http://docs.jquery.com/Attributes/html#val pour plus d'informations.

10
Nyla Pareska
  1. Méthodes DOM, comme indiqué par Tom.

  2. innerHTML, comme mentionné par iHunger.

Les méthodes DOM sont très préférables aux chaînes pour définir les attributs et le contenu. Si vous vous retrouvez à écrire innerHTML= '<a href="'+path+'">'+text+'</a>', Vous créez en fait de nouveaux trous de sécurité de script intersite côté client, ce qui est un peu triste si vous avez passé du temps à sécuriser votre côté serveur.

Les méthodes DOM sont traditionnellement décrites comme "lentes" par rapport à innerHTML. Mais ce n'est pas vraiment toute l'histoire. Ce qui est lent, c'est l'insertion de nombreux nœuds enfants:

 for (var i= 0; i<1000; i++)
     div.parentNode.insertBefore(document.createElement('div'), div);

Cela se traduit par une charge de travail pour le DOM de trouver le bon endroit dans sa liste de nœuds pour insérer l'élément, de déplacer les autres nœuds enfants vers le haut, d'insérer le nouveau nœud, de mettre à jour les pointeurs, etc.

Par contre, définir la valeur d'un attribut existant ou les données d'un nœud de texte est très rapide; vous venez de changer un pointeur de chaîne et c'est tout. Cela va être beaucoup plus rapide que la sérialisation du parent avec innerHTML, sa modification et son analyse (et ne perdra pas vos données non sérialisables comme les gestionnaires d'événements, les références JS et les valeurs de formulaire).

Il existe des techniques pour effectuer des manipulations DOM sans marcher trop lentement avec les nœuds childNodes. En particulier, soyez conscient des possibilités de cloneNode et de l'utilisation de DocumentFragment. Mais parfois innerHTML est vraiment plus rapide. Vous pouvez toujours obtenir le meilleur des deux mondes en utilisant innerHTML pour écrire votre structure de base avec des espaces réservés pour les valeurs d'attribut et le contenu du texte, que vous remplissez ensuite en utilisant DOM. Cela vous évite d'avoir à écrire votre propre fonction escapehtml() pour contourner les problèmes d'échappement/de sécurité mentionnés ci-dessus.

9
bobince

Vous pouvez à la place modifier le innerHTML ou outerHTML d'un élément sur la page.

3
iHunger

Je ne suis pas particulièrement doué pour JavaScript ou ses meilleures pratiques, mais document.write() avec innerHtml() vous permet essentiellement d'écrire des chaînes qui peuvent ou non être HTML valide; ce ne sont que des personnages. En utilisant le DOM, vous garantissez un code HTML approprié et conforme aux normes qui empêchera votre page de se briser via un code HTML clairement mauvais.

Et, comme Tom l'a mentionné, JavaScript est effectué après le chargement de la page; il serait probablement préférable de faire la configuration initiale de votre page via HTML standard (via des fichiers .html ou tout ce que fait votre serveur [c'est-à-dire php]).

2
RoyalKnight

La meilleure façon est sûrement d'éviter de faire du HTML lourd creation dans votre JavaScript? Le balisage envoyé depuis le serveur doit contenir la majeure partie de celui-ci, que vous pouvez ensuite manipuler, en utilisant CSS plutôt que de supprimer/remplacer des éléments par force brute, si possible.

Cela ne s'applique pas si vous faites quelque chose de "intelligent" comme émuler un système de widgets.

1
Rob

element.InnerHtml= allmycontent: Réécrira tout à l'intérieur de l'élément. Vous devez utiliser une variable let allmycontent="this is what I want to print inside this element" Pour stocker tout le contenu que vous souhaitez à l'intérieur de cet élément. Sinon à chaque fois que vous appellerez cette fonction, le contenu de votre élément sera effacé et remplacé par le dernier appel que vous en aurez fait.

document.write(): peut être utilisé plusieurs fois, chaque fois que le contenu sera imprimé là où l'appel est passé sur la page.

Mais sachez que la méthode document.write () est niquement utile pour insérer du contenu lors de la création d'une page. Alors utilisez-le pour ne pas répéter lorsque vous avez beaucoup de données à écrire comme un catalogue de produits ou d'images.

Voici un exemple simple: tous vos li pour votre menu aparté sont stockés dans un tableau "tab", vous pouvez créer un script js avec la balise script directement dans la page html puis utiliser l'écriture dans une fonction itérative où vous souhaitez insérer ces li sur la page.

<script type="text/javascript">
document.write("<ul>");
for (var i=0; i<=tab.length; i++){
    document.write(tab[i]);
    }document.write("</ul>");
</script>`

Cela fonctionne car Js est interprété de manière linéaire lors du chargement. Assurez-vous donc que votre script est au bon endroit dans votre page html.Vous pouvez également utiliser un fichier Js externe, mais vous devez le déclarer à l'endroit où vous souhaitez qu'il soit interprété.

Pour cette raison, document.write ne peut pas être appelé pour écrire quelque chose sur votre page à la suite d'un "interaction utilisateur" (comme un clic ou un survol), car alors le DOM a été créé et la méthode d'écriture va, comme dit ci-dessus, écrire une nouvelle page (purger la pile d'exécution réelle et démarrer une nouvelle pile et une nouvelle arborescence DOM). Dans ce cas, utilisez:

element.innerHTML=("Myfullcontent");

Pour en savoir plus sur les méthodes du document: ouvrez votre console: document; Puis ouvrez: __proto__: HTMLDocumentPrototype

Vous verrez la propriété de fonction "écrire" dans l'objet document. Vous pouvez également utiliser document.writeln qui ajoute une nouvelle ligne à chaque instruction. Pour en savoir plus sur une fonction/méthode, écrivez simplement son nom dans la console sans parenthèses: document.write; La console renverra une description au lieu de l'appeler.

1
Myriam Rouve

Il existe de nombreuses façons d'écrire du HTML avec JavaScript.

document.write n'est utile que lorsque vous souhaitez écrire sur une page avant qu'elle ne soit réellement chargée. Si vous utilisez document.write () après le chargement de la page (lors de l'événement onload), il créera une nouvelle page et écrasera l'ancien contenu. De plus, cela ne fonctionne pas avec XML, qui inclut XHTML.

D'un autre côté, d'autres méthodes ne peuvent pas être utilisées avant la création de DOM (page chargée), car elles fonctionnent directement avec DOM.

Ces méthodes sont:

  • node.innerHTML = "Peu importe";
  • document.createElement ('div'); et node.appendChild (), etc.

Dans la plupart des cas, node.innerHTML est meilleur car il est plus rapide que les fonctions DOM. La plupart du temps, cela rend également le code plus lisible et plus petit.

1
Maiku Mori

Utilisez jquery, regardez comme c'est facile:

    var a = '<h1> this is some html </h1>';
    $("#results").html(a);

       //html
    <div id="results"> </div>
0
csandreas1

La méthode document.write est très limitée. Vous ne pouvez l'utiliser que lorsque le chargement de la page est terminé. Vous ne pouvez pas l'utiliser pour mettre à jour le contenu d'une page chargée.

Ce que vous voulez probablement, c'est innerHTML .

0
Mike Daniels

Je pense que vous devriez utiliser, au lieu de document.write, API JavaScript DOM comme document.createElement, .createTextNode, .appendChild et similaire. Navigateur sûr et presque croisé.

ihunger'souterHTML n'est pas un navigateur croisé, c'est IE uniquement.

0
Luca