web-dev-qa-db-fra.com

Remplacement efficace de la chaîne Javascript

Hé, j'ai un bloc de code HTML que je vais utiliser de manière répétée (à différents moments de la visite d'un utilisateur, pas tout de suite). Je pense que le meilleur moyen d'y parvenir est de créer une div HTML, de la masquer et, le cas échéant, de prendre son innerHTML et de remplacer () plusieurs mots-clés. Exemple de bloc HTML ...

<div id='sample'>
  <h4>%TITLE%</h4>
  <p>Text text %KEYWORD% text</p>
  <p>%CONTENT%</p>
  <img src="images/%ID%/1.jpg" />
</div>

Le meilleur moyen de remplacer ces mots-clés par des données dynamiques serait-il d'aller ...

template = document.getElementById('sample');
template = template.replace(/%TITLE%/, some_var_with_title);
template = template.replace(/%KEYWORD%/, some_var_with_keyword);
template = template.replace(/%CONTENT%/, some_var_with_content);
template = template.replace(/%ID%/, some_var_with_id);

C'est comme si j'avais choisi une façon stupide de faire ça. Quelqu'un a-t-il des suggestions sur la manière de procéder plus rapidement, plus intelligemment ou mieux, de quelque manière que ce soit? Ce code sera exécuté assez souvent lors de la visite d’un utilisateur, parfois aussi souvent qu’une fois toutes les 3 à 4 secondes.

Merci d'avance.

30
Josh

Je doute qu'il y ait quelque chose de plus efficace. L’alternative serait de la scinder en plusieurs parties, puis de la concaténer, mais je ne pense pas que ce serait très efficace. Peut-être même moins, étant donné que chaque concaténation donne une nouvelle chaîne qui a la même taille que ses opérandes.

Ajoutée: C'est probablement la manière la plus élégante d'écrire ceci. En plus de quoi t'inquiètes-tu? Utilisation de la mémoire? Il est abondant et Javascript a un gestionnaire de mémoire décent. Vitesse d'exécution? Ensuite, vous devez avoir une ficelle gigantesque. IMHO c'est bon.

12
Vilx-

Il semble que vous souhaitiez utiliser un modèle.

//Updated 28 October 2011: Now allows 0, NaN, false, null and undefined in output. 
function template( templateid, data ){
    return document.getElementById( templateid ).innerHTML
      .replace(
        /%(\w*)%/g, // or /{(\w*)}/g for "{this} instead of %this%"
        function( m, key ){
          return data.hasOwnProperty( key ) ? data[ key ] : "";
        }
      );
}

Explication du code:

  • Exige que templateid soit l'identifiant d'un élément existant.
  • Exige que data soit un objet avec les données.
  • Utilise deux paramètres à remplacer pour effectuer la substitution:
  • La première est une expression rationnelle qui recherche tout %keys% (ou {keys} si vous utilisez la version alternative). La clé peut être une combinaison de AZ, aZ, 0-9 et trait de soulignement _.
  • La seconde est une fonction anonyme qui est appelée pour chaque match.
  • La fonction anonyme recherche dans la base de données la clé trouvée par l'expression rationnelle. Si la clé est trouvée dans les données, la valeur de la clé est renvoyée et cette valeur remplacera la clé dans la sortie finale. Si la clé n'est pas trouvée, une chaîne vide est renvoyée.

Exemple de modèle:

<div id="mytemplate">
  <p>%test%</p>
  <p>%Word%</p>
</div>

Exemple d'appel:

document.getElementById("my").innerHTML=template("mytemplate",{test:"MYTEST",Word:"MYWORD"});
78
some

Vous pourriez probablement adapter ce code pour faire ce que vous voulez:

var user = {
    "firstName": "John",
    "login": "john_doe",
    "password": "test",
};

var textbody = ""
+"Hey {firstName},\n"
+"\n"
+"You recently requested your password.\n"
+"login: {login}\n"
+"password: {password}\n"
+"\n"
+"If you did not request your password, please disregard this message.\n"
+"";

textbody = textbody.replace(/{[^{}]+}/g, function(key){
    return user[key.replace(/[{}]+/g, "")] || "";
});

Vous voudrez peut-être aussi regarder dans JavaScriptTemplates

18
Kristof Neirynck

Remplacement de modèle

Une solution simple et rapide consiste à utiliser la méthode String.prototype.replace . Il faut un deuxième paramètre qui peut être une valeur ou une fonction:

function replaceMe(template, data) {
    const pattern = /\{(.*?)\}/g; // {property}
    return template.replace(pattern, (match, token) => data[token]);
}

Exemple :

const html = `
    <div>
        <h4>{title}</h4>
        <p>My name is {name}</p>
        <img src="{url}" />
    </div>
`;

const data = {
    title: 'My Profile',
    name: 'John Smith',
    url: 'http://images/john.jpeg'
};

Et appelez comme ça:

replaceMe(html, data);
6
Lior Elrom

Votre méthode est un moyen standard d'implémenter le système de gabarit des pauvres, alors tout va bien.

Cela pourrait valoir la peine de consulter certaines bibliothèques de templates JavaScript, telles que JST .

1
orip

Cette approche génère des modèles de fonction pouvant être mis en cache:

function compileMessage (message) {

  return new Function('obj', 'with(obj){ return \'' +
    message.replace(/\n/g, '\\n').split(/{{([^{}]+)}}/g).map(function (expression, i) {
      return i%2 ? ( '\'+(' + expression.trim() + ')+\'' ) : expression;
    }).join('') + 
  '\'; }');

}

var renderMessage = compileMessage('Hi {{ recipient.first_name }},\n\n' +

'Lorem ipsum dolor sit amet...\n\n' +

'Best Regarts,\n\n' +

'{{ sender.first_name }}');


renderMessage({
  recipient: {
    first_name: 'John'
  },
  sender: {
    first_name: 'William'
  }
});

résultats:

"Hi John,

Lorem ipsum dolor sit amet...

Best Regarts,

William"
1
Jesús Germade

Vous pouvez le rendre plus efficace en enchaînant les remplaçants au lieu de faire toutes ces tâches provisoires.

c'est à dire. 

with(document.getElementById('sample'))
{
  innerHTML = innerHTML.replace(a, A).replace(b, B).replace(c, C); //etc
}
1
annakata

Si vous souhaitez utiliser la bibliothèque de prototypes , ils disposent de la fonctionnalité de modèles intégrée à Nice.

Cela ressemblerait à:

element.innerHTML = (new Template(element.innerHTML)).evaluate({
    title: 'a title',
    keyword: 'some keyword',
    content: 'A bunch of content',
    id: 'id here'
})

Cela serait particulièrement pratique si vous exécutiez votre code dans une boucle en raison de la facilité de création d’objets JSON/littéraux d’objets Javascript. 

Cependant, je ne m'attendrais pas à une augmentation de la vitesse.

De plus, vous devrez changer votre style de délimiteur en #{keyword} au lieu de %keyword%

1
Triptych

Essayez ceci: http://json2html.com/

Il prend également en charge les objets JSON complexes.

0
sura2k

Moustachejs est idéal pour créer des modèles vraiment élégants:

<div id='sample'>
  <h4>{{TITLE}}</h4>
  <p>Text text {{KEYWORD}} text</p>
  <p>{{CONTENT}}</p>
  <img src="images/{{ID}}/1.jpg" />
</div>

Vous pouvez ensuite utiliser le modèle comme ceci:

var template = document.getElementById(templateid).innerHTML;
var newHtml = Mustache.render(template, {
    TITLE: some_var_with_title,
    KEYWORD: some_var_with_keyword,
    CONTENT: some_var_with_content,
    ID: some_var_with_id
});
document.getElementById('sample').innerHTML = newHtml;

Cela fonctionne particulièrement bien si vous récupérez du JSON après un appel Ajax - vous pouvez simplement le transmettre directement à l’appel Mustache.render().

De légères variations permettent d'exécuter le même modèle sur le navigateur ou le serveur. Voir https://github.com/janl/mustache.js pour plus de détails.

0
Philip Callender