web-dev-qa-db-fra.com

Existe-t-il une meilleure pratique pour générer du HTML avec Javascript

J'appelle un service Web qui renvoie un tableau d'objets en JSON. Je veux prendre ces objets et remplir un div avec HTML. Disons que chaque objet contient une URL et un nom.

Si je voulais générer le code HTML suivant pour chaque objet:

<div><img src="the url" />the name</div>

Existe-t-il une meilleure pratique pour cela? Je peux voir quelques façons de le faire:

  1. Concaténer des chaînes
  2. Créer des éléments
  3. Utilisez un plugin de modèles
  4. Générez le html sur le serveur, puis servez-vous via JSON.
96
ckarbass

Les options # 1 et # 2 seront vos options directes les plus immédiates, cependant, pour les deux options, vous ressentirez l'impact sur les performances et la maintenance en créant des chaînes ou en créant des objets DOM.

Les modèles ne sont pas si immatures, et vous le voyez apparaître dans la plupart des principaux frameworks Javascript.

Voici un exemple dans JQuery Template Plugin qui vous permettra d'économiser les performances et est vraiment très simple:

var t = $.template('<div><img src="${url}" />${name}</div>');

$(selector).append( t , {
     url: jsonObj.url,
     name: jsonObj.name
});

Je dis aller dans la bonne direction (et mieux performant, plus maintenable) et utiliser les modèles.

64
Jim Fiorato

Si vous devez absolument concaténer des chaînes, au lieu de la normale:

var s="";
for (var i=0; i < 200; ++i) {s += "testing"; }

utilisez un tableau temporaire:

var s=[];
for (var i=0; i < 200; ++i) { s.Push("testing"); }
s = s.join("");

L'utilisation de tableaux est beaucoup plus rapide, en particulier dans IE. J'ai fait quelques tests avec des chaînes il y a quelque temps avec IE7, Opera et FF. Opera n'a pris que 0,4 seconde pour effectuer le test, mais IE7 n'avait pas terminé après 20 MINUTES !!!! (Non, je ne plaisante pas.) Avec array IE était très rapide.

13
some

L'une ou l'autre des deux premières options est à la fois courante et acceptable.

Je vais donner des exemples de chacun dans Prototype .

// assuming JSON looks like this:
// { 'src': 'foo/bar.jpg', 'name': 'Lorem ipsum' }

Approche n ° 1:

var html = "<div><img src='#{src}' /> #{name}</div>".interpolate(json);
$('container').insert(html); // inserts at bottom

Approche n ° 2:

var div = new Element('div');
div.insert( new Element('img', { src: json.src }) );
div.insert(" " + json.name);
$('container').insert(div); // inserts at bottom
8
savetheclocktower

Une approche plus moderne consiste peut-être à utiliser un langage de modèle tel que Moustache , qui a des implémentations dans de nombreuses langues, y compris javascript. Par exemple:

var view = {
  url: "/hello",
  name: function () {
    return 'Jo' + 'hn';
  }
};

var output = Mustache.render('<div><img src="{{url}}" />{{name}}</div>', view);

Vous obtenez même un avantage supplémentaire - vous pouvez réutiliser les mêmes modèles dans d'autres endroits, tels que le côté serveur.

Si vous avez besoin de modèles plus compliqués (instructions, boucles, etc.), vous pouvez utiliser Guidons qui a plus de fonctionnalités et est compatible avec Moustache.

7
Tzach

Voici un exemple, en utilisant mon plug-in Modèles simples pour jQuery:

var tmpl = '<div class="#{classname}">#{content}</div>';
var vals = {
    classname : 'my-class',
    content   : 'This is my content.'
};
var html = $.tmpl(tmpl, vals);
6
Andrew Hedges

Vous pouvez ajouter le modèle HTML à votre page dans un div caché, puis utiliser cloneNode et les fonctions de requête de votre bibliothèque préférée pour le remplir

/* CSS */
.template {display:none;}

<!--HTML-->
<div class="template">
  <div class="container">
    <h1></h1>
    <img src="" alt="" />
  </div>
</div>

/*Javascript (using Prototype)*/
var copy = $$(".template .container")[0].cloneNode(true);
myElement.appendChild(copy);
$(copy).select("h1").each(function(e) {/*do stuff to h1*/})
$(copy).select("img").each(function(e) {/*do stuff to img*/})
4
Leo

Divulgation: je suis le mainteneur de BOB.

Il existe une bibliothèque javascript qui rend ce processus beaucoup plus facile appelé BOB .

Pour votre exemple spécifique:

<div><img src="the url" />the name</div>

Cela peut être généré avec BOB par le code suivant.

new BOB("div").insert("img",{"src":"the url"}).up().content("the name").toString()
//=> "<div><img src="the url" />the name</div>"

Ou avec la syntaxe plus courte

new BOB("div").i("img",{"src":"the url"}).up().co("the name").s()
//=> "<div><img src="the url" />the name</div>"

Cette bibliothèque est assez puissante et peut être utilisée pour créer des structures très complexes avec insertion de données (similaire à d3), par exemple:

data = [1,2,3,4,5,6,7]
new BOB("div").i("ul#count").do(data).i("li.number").co(BOB.d).up().up().a("a",{"href": "www.google.com"}).s()
//=> "<div><ul id="count"><li class="number">1</li><li class="number">2</li><li class="number">3</li><li class="number">4</li><li class="number">5</li><li class="number">6</li><li class="number">7</li></ul></div><a href="www.google.com"></a>"

BOB ne prend actuellement pas en charge l'injection des données dans le DOM. C'est sur la todolist. Pour l'instant, vous pouvez simplement utiliser la sortie avec JS ou jQuery normal et la placer où vous le souhaitez.

document.getElementById("parent").innerHTML = new BOB("div").insert("img",{"src":"the url"}).up().content("the name").s();
//Or jquery:
$("#parent").append(new BOB("div").insert("img",{"src":"the url"}).up().content("the name").s());

J'ai créé cette bibliothèque parce que je n'étais pas satisfait de l'une des alternatives comme jquery et d3. Le code est très compliqué et difficile à lire. Travailler avec BOB est à mon avis, ce qui est évidemment biaisé, beaucoup plus agréable.

BOB est disponible sur Bower , vous pouvez donc l'obtenir en exécutant bower install BOB.

3
Automatico

Existe-t-il une meilleure pratique pour cela? Je peux voir quelques façons de le faire:

  1. Concaténer des chaînes
  2. Créer des éléments
  3. Utilisez un plugin de modèles
  4. Générez le html sur le serveur, puis servez-vous via JSON.

1) Ceci est une option. Construisez le html avec JavaScript côté client, puis injectez-le dans le DOM dans son ensemble.

Notez qu'il existe un paradigme derrière cette approche: le serveur génère uniquement des données et (en cas d'interaction) reçoit des données du client asyncronoulsy avec des requêtes AJAX. Le code côté client fonctionne comme un stand- seule application web JavaScript.

L'application Web peut fonctionner, rendre l'interface, même sans que le serveur ne soit actif (bien sûr, elle n'affichera aucune donnée ni n'offrira aucune sorte d'interaction).

Ce paradigme est adopté souvent ces derniers temps, et des cadres entiers sont construits autour de cette approche (voir backbone.js par exemple).

2) Pour des raisons de performances, lorsque cela est possible, il est préférable de construire le code HTML dans une chaîne, puis de l'injecter dans son ensemble dans la page.

) Ceci est une autre option, ainsi que l'adoption d'un cadre d'application Web. D'autres utilisateurs ont publié divers moteurs de modèles disponibles. J'ai l'impression que vous avez les compétences pour les évaluer et décider de suivre ou non cette voie.

4) Une autre option. Mais servez-le comme un texte brut/html; pourquoi JSON? Je n'aime pas cette approche car elle mélange PHP (votre langage serveur) avec du HTML. Mais je l'adopte souvent comme un compromis raisonnable entre l'option 1 et 4.


Ma réponse: vous regardez déjà dans la bonne direction.

Je suggère d'adopter une approche entre 1 et 4 comme je le fais. Sinon, adoptez un cadre Web ou un moteur de modèles.

Juste mon opinion basée sur mon expérience ...

2
Paolo