我正在使用javascript和新的html template
标记构建一个多语言单页网站,并希望在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上循环更快的解决方案是什么?
其他图书馆like AngularJS如何使用{{ 'FOO' | translate }}
?
答案 0 :(得分:2)
我认为最大的问题是,您不仅要运行正则表达式,还要在整个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('');
}
答案 1 :(得分:1)
您可以使用正则表达式(稍加修改)将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;
答案 2 :(得分:0)
考虑使用现有的模板引擎,而不是构建自己的模板引擎。那里有很多人,而且他们的速度非常快。
在此评估一些选项: http://garann.github.io/template-chooser/
handlebarsjs似乎是引导者。
约翰·雷西格(John Ressig)发表了一篇精彩的微观模板&#34;与您的解决方案类似的解决方案。 (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>