繁体   English   中英

Javascript更快地替换HTML代码中的“变量”

[英]Javascript replace “variables” in HTML code faster

我正在使用javascript和新的html template -tag构建多语言的单页网站,并希望在html中使用自己的变量,例如{{txt.welcome}} ,应将其替换为翻译。

HTML:

<div class="container">
  <h2>{{heading.hello}}</h2>
  <p>{{txt.welcome}}<br /><img alt="{{image.description}}" src="" /></p>
</div>

使用Javascript:

var reg = new RegExp(/{{([a-z.]+)}}/g);
var result;
while(result = reg.exec(document.documentElement.innerHTML)) {
    document.documentElement.innerHTML = document.documentElement.innerHTML.replace(result[0], translations[result[1]]);
}

它会在整个文档中搜索变量,并用定义的文本替换它们,但是对于许多变量,性能确实很差。

有什么比在整个文档的html上循环使用正则表达式更快的解决方案?

如何做到这一点其他图书馆像AngularJS{{ 'FOO' | translate }} {{ 'FOO' | translate }}

我认为,最大的问题是您不仅要运行正则表达式,而且还要在整个HTML上运行替换多次 而且您要设置实际的DOM HTML多次,而不是操纵字符串直到获得结果,然后再设置一次HTML。 我强烈建议使用像Handlebars.js这样的库,但是如果您想自己做,那么一个非常快速的实现将是:

var translations = { 
    heading: { 
        hello: "hello" 
    }, 
    txt: { 
        welcome: "welcome" 
    }, 
    image: { 
        description: "this is a test" 
    }
};

function get(obj, desc) {
    var arr = desc.split(".");
    while(arr.length && (obj = obj[arr.shift()]));
    return obj;
}

function replaceTokens(HTML) {
    return HTML.split('{{').map(function(i) { 
        var symbol = i.substring(0, i.indexOf('}}')).trim(); 
        return i.replace(symbol + '}}', get(translations, symbol)); 
    }).join('');
}

您可以使用regexp(稍作修改)将html拆分为一个数组。 然后,您只能用其翻译替换数组的模板块,然后将其加入并用它替换文档html:

var html = "a little {{foo}} in the {{bar}}"; // replace with document.documentElement.innerHTML
var translations = {foo: "boy", bar: "garden"};
var chunks = html.split(/({{[a-z.]+}})/g);
var chunksTranslated = chunks.map(function(chunk){
  if(chunk.slice(0,2)==="{{" && chunk.slice(-2)==="}}") {
    var id = chunk.slice(2,-2);
    return translations[id];
  }
  return chunk;
});
var translatedHtml = chunksTranslated.join("");
//document.documentElement.innerHTML = translatedHtml;

考虑使用现有的模板引擎,而不是构建自己的模板引擎。 他们中有很多人,而且他们的速度很快。

在此处评估一些选项: http : //garann.github.io/template-chooser/

handlebarsjs似乎是引擎。

John Ressig发布了一个很棒的“微型模板”解决方案,与您的解决方案类似。 http://ejohn.org/blog/javascript-micro-templating/

 // Simple JavaScript Templating // John Resig - http://ejohn.org/ - MIT Licensed (function(){ var cache = {}; this.tmpl = function tmpl(str, data){ // Figure out if we're getting a template, or if we need to // load the template - and be sure to cache the result. var fn = !/\\W/.test(str) ? cache[str] = cache[str] || tmpl(document.getElementById(str).innerHTML) : // Generate a reusable function that will serve as a template // generator (and which will be cached). new Function("obj", "var p=[],print=function(){p.push.apply(p,arguments);};" + // Introduce the data as local variables using with(){} "with(obj){p.push('" + // Convert the template into pure JavaScript str .replace(/[\\r\\t\\n]/g, " ") .split("<%").join("\\t") .replace(/((^|%>)[^\\t]*)'/g, "$1\\r") .replace(/\\t=(.*?)%>/g, "',$1,'") .split("\\t").join("');") .split("%>").join("p.push('") .split("\\r").join("\\\\'") + "');}return p.join('');"); // Provide some basic currying to the user return data ? fn( data ) : fn; }; })(); 

您可以将其用于这样编写的模板(不必采用这种特殊方式,但是我喜欢这种样式):

 <script type="text/html" id="item_tmpl"> <div id="<%=id%>" class="<%=(i % 2 == 1 ? " even" : "")%>"> <div class="grid_1 alpha right"> <img class="righted" src="<%=profile_image_url%>"/> </div> <div class="grid_6 omega contents"> <p><b><a href="/<%=from_user%>"><%=from_user%></a>:</b> <%=text%></p> </div> </div> </script> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM