2009-10-07 3 views
59

Je vois dans certains articles que les gens désapprouvent l'utilisation de document.write() en javascript lors de l'écriture HTML dynamique.Quelle est la bonne façon d'écrire du HTML en utilisant Javascript?

Pourquoi est-ce? et quelle est la correcte façon?

+6

JQuery. Je n'ai pas ajouté cela comme une réponse réelle, mais je suis venu près. Il gère correctement la manipulation dom, tout en vous permettant d'écrire quelque chose de simple comme ceci: $ ("

text
sub
") .appendTo ('body'); –

+2

C'est un cas où le mème jQuery a vraiment du sens. "Je vois que vous essayez d'écrire du HTML en utilisant JavaScript, vous devriez laisser tomber ça et utiliser jQuery!" –

+4

jQuery n'est en aucun cas le moyen "correct" de créer du HTML en JavaScript. Il est écrit en JavaScript et utilisera une ou plusieurs des méthodes dans les réponses ci-dessous, avec l'inconvénient qu'en tant que bibliothèque à usage général, il ne fera pas les choix éclairés de la stratégie pour chaque situation que vous en tant que développeur aurait. –

Répondre

40

document.write() ne fonctionnera que pendant l'analyse initiale de la page et la création du DOM. Une fois que le navigateur arrive à 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 de votre situation. Dans certains cas, vous avez juste besoin d'avoir document.write() pour accomplir la tâche. Regardez comment Google Analytics est injecté dans la plupart des sites Web.

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

  1. Utilisation innerHTML sur un nœud:

    var node = document.getElementById('node-id'); 
    node.innerHTML('<p>some dynamic html</p>'); 
    
  2. Utilisation de 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 est peut-être la méthode la plus simple, mais il est prouvé que innerHTML est beaucoup plus rapide et est utilisé sous le capot dans les bibliothèques JavaScript telles que jQuery.

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

+0

Vous pouvez l'utiliser, essayez-le =). Ce n'est probablement pas ce que vous voulez faire, mais vous pouvez toujours le faire. –

+0

Une belle réponse complète, merci. Je comprends maintenant que document.write() n'est utile que lorsque la page est chargée et créée pour la première fois. Pour mettre à jour dynamiquement la page par la suite, les méthodes DOM ou innerHTML() sont obligatoires. –

+0

Pourriez-vous fournir la preuve que innerHTML est toujours plus rapide? Je doute que ce soit toujours le cas. Si vous ajoutez des nœuds un par un à un nœud existant dans le DOM, je pense que innerHTML est plus rapide car le navigateur doit potentiellement manipuler et rendre à nouveau des parties du document à chaque étape, mais si vous créez un nouvel arbre de nœuds et ajouter son noeud racine au DOM à la fin, je m'attendrais à ce que cela soit aussi rapide ou plus rapide que l'utilisation de innerHTML. –

26

document.write() ne fonctionne pas avec XHTML. Il est exécuté après la page a terminé le chargement et ne fait rien de plus que d'écrire une chaîne de HTML. Puisque la représentation réelle en mémoire de HTML 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 y arriveriez serait de créer par programme vos nœuds, puis de les attacher à un emplacement existant dans le DOM. Pour fins d'un [artificielle] par exemple, en supposant que j'ai un élément div maintenant un attribut ID de « tête », alors je pourrais présenter un texte dynamique en faisant ceci:

// 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); 
+4

Il est effectivement exécuté lorsque vous l'appelez.Si vous l'appelez après le chargement de la page, il écrasera le contenu. –

+2

Restez en HTML et 'document.write' reste un outil utile. –

3

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

+2

De préférence innerHTML, car outerHTML n'est pas largement supporté. – bobince

0

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

Ce que vous voulez probablement est innerHTML.

2

Je ne suis pas particulièrement grande au 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 sont juste des caractères. En utilisant le DOM, vous vous assurez un code HTML approprié, conforme aux normes, qui empêchera votre page de se rompre via un code HTML clairement incorrect. Et, comme Tom l'a mentionné, JavaScript est fait après le chargement de la page; il serait probablement préférable d'avoir la configuration initiale pour votre page à faire via HTML standard (via des fichiers .html ou tout ce que votre serveur fait [c'est-à-dire php]).

+1

Si vous écrivez des composants dynamiques en utilisant javascript, vous finirez par écrire sur DOM avec javascript. Alors que document.write() n'est pas vraiment la solution, vous utiliserez probablement innerHTML dans la plupart des cas. Puisque innerHTML est beaucoup plus rapide, utilisez createNode/appendChild dans tous les navigateurs. C'est très important quand vous devez générer beaucoup d'éléments html/DOM. + c'est document, pas de document;) –

1

Il existe plusieurs façons d'écrire du code HTML avec JavaScript. Document.write n'est utile que si vous voulez é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 d'un événement onload), une nouvelle page sera créée et l'ancien contenu sera remplacé. En outre, cela ne fonctionne pas avec XML, qui inclut XHTML. D'autre part, d'autres méthodes ne peuvent pas être utilisées avant que DOM ait été créé (page chargée), car elles fonctionnent directement avec DOM.

Ces méthodes sont les suivantes:

  • node.innerHTML = "Quelle que soit";
  • 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 le code plus lisible et plus petit.

0

Je pense que vous devriez utiliser, au lieu de document.write, DOM JavaScript API comme document.createElement, .createTextNode, .appendChild et similaire. Coffre-fort et presque traverser le navigateur.

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

9
  1. Les méthodes DOM, comme indiqué par Tom.

  2. innerHTML, comme mentionné par iHunger.

Les méthodes DOM sont hautement préférables aux chaînes pour définir les attributs et le contenu. Si vous vous trouvez en train d'écrire innerHTML= '<a href="'+path+'">'+text+'</a>', vous êtes en train de créer de nouvelles failles de sécurité pour les scripts intersites du côté client, ce qui est un peu triste si vous avez passé du temps à sécuriser votre 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 est l'insertion d'un grand nombre de 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 les DOM trouver le bon endroit dans son nodelist d'insérer l'élément, déplacer l'autre nœuds enfants jusqu'à, insérer la nouvelle nœud, mise à jour des pointeurs, etc.

La définition d'une valeur d'attribut existante ou des données d'un nœud de texte, par contre, est très rapide; vous venez de changer un pointeur de chaîne et c'est tout. Cela va être beaucoup plus rapide que de sérialiser le parent avec innerHTML, de le changer et de l'analyser de nouveau (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 y a des techniques pour faire des manipulations de DOM sans tant de childNodes lentes marchant. En particulier, soyez conscient des possibilités de cloneNode, et en utilisant 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.

8

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

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

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

+2

Pourquoi cela a-t-il été rejeté? –

+3

Parce que les gens parlent de la manière plus élégante, plus rapide et multi-navigateur de faire quelque chose, et d'avoir à charger jQuery pour y parvenir, ce n'est pas une réponse. – Lennon

1

Sûrement le meilleur moyen est d'éviter de faire tout lourd HTML création dans votre JavaScript? Le balisage envoyé par le serveur doit en contenir la majeure partie, que vous pouvez ensuite manipuler, en utilisant CSS plutôt que de supprimer/remplacer des éléments brutaux, si cela est possible.

Ceci ne s'applique pas si vous faites quelque chose de "malin" comme émuler un système de widget.

0

Utilisez jquery, regardez combien il est facile:

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

     //html 
    <div id="results"> </div> 
Questions connexes