Эффективная замена строки Javascript
Эй, у меня есть блок HTML, который я буду использовать повторно (в разное время во время посещения пользователя, а не сразу). Я думаю, что лучший способ достичь этого - создать HTML-div, скрыть его, и при необходимости взять его innerHTML и сделать replace() по нескольким ключевым словам. В качестве примера блока HTML...
<div id='sample'>
<h4>%TITLE%</h4>
<p>Text text %KEYWORD% text</p>
<p>%CONTENT%</p>
<img src="images/%ID%/1.jpg" />
</div>
Будет ли лучший способ заменить эти ключевые слова динамическими данными, чтобы идти...
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);
Просто кажется, что я выбрал глупый способ сделать это. Есть ли у кого-нибудь какие-либо предложения о том, как это сделать быстрее, умнее или лучше? Этот код будет выполняться довольно часто во время посещения пользователей, иногда так же часто, как раз каждые 3-4 секунды.
Спасибо заранее.
Ответы
Ответ 1
Я сомневаюсь, что будет что-то более эффективное. Альтернативой было бы разделение его на части, а затем на конкатенацию, но я не думаю, что это было бы очень эффективно. Возможно, даже меньше, учитывая, что каждая конкатенация приводит к новой строке, которая имеет тот же размер, что и ее операнды.
Добавлено: Это, наверное, самый элегантный способ написать это. Кроме того, о чем вы беспокоитесь? Использование памяти? Это много, и у Javascript есть приличный менеджер памяти. Скорость выполнения? Тогда у вас должна быть какая-то гигантская строка. ИМХО это хорошо.
Ответ 2
Похоже, вы хотите использовать шаблон.
//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 ] : "";
}
);
}
Объяснение кода:
- Ожидает
templateid
как идентификатор существующего элемента.
- Ожидает, что
data
будет объектом с данными.
- Используется два параметра для замены:
- Первым является регулярное выражение, которое ищет все
%keys%
(или {keys}
, если вы используете альтернативную версию). Ключ может быть комбинацией A-Z, a-z, 0-9 и подчеркивания _.
- Вторая - анонимная функция, которая вызывается для каждого соответствия.
- Анонимная функция выполняет поиск объекта данных для ключа, найденного regexp.
Если ключ найден в данных, тогда возвращается значение ключа, и это значение будет заменять ключ в конечном выходе. Если ключ не найден, возвращается пустая строка.
Пример шаблона:
<div id="mytemplate">
<p>%test%</p>
<p>%word%</p>
</div>
Пример вызова:
document.getElementById("my").innerHTML=template("mytemplate",{test:"MYTEST",word:"MYWORD"});
Ответ 3
Вероятно, вы можете адаптировать этот код для выполнения того, что вы хотите:
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, "")] || "";
});
Вы также можете посмотреть JavaScriptTemplates
Ответ 4
Быстрое и простое решение - использовать метод String.prototype.replace.
Он принимает второй параметр, который может быть значением или функцией:
function replaceMe(template, data) {
const pattern = /{\s*(\w+?)\s*}/g; // {property}
return template.replace(pattern, (_, token) => data[token] || '');
}
Пример:
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'
};
И называй это так:
replaceMe(html, data);
Ответ 5
Ваш метод является стандартным способом внедрения системы шаблонов для слабого человека, поэтому это хорошо.
Возможно, вам стоит проверить некоторые библиотеки шаблонов JavaScript, такие как JST.
Ответ 6
Вы можете сделать это более эффективным, объединив замены вместо выполнения всех этих промежуточных заданий.
то есть.
with(document.getElementById('sample'))
{
innerHTML = innerHTML.replace(a, A).replace(b, B).replace(c, C); //etc
}
Ответ 7
Если вы хотите использовать Prototype library, у них есть хорошая встроенная функциональность для шаблонов.
Это будет выглядеть так:
element.innerHTML = (new Template(element.innerHTML)).evaluate({
title: 'a title',
keyword: 'some keyword',
content: 'A bunch of content',
id: 'id here'
})
Это было бы особенно приятно, если бы вы запускали свой код в цикле из-за простоты создания объектов JSON/Javascript-объектов.
Тем не менее, я бы не ожидал увеличения скорости.
Кроме того, вам нужно будет изменить стиль разделителя на #{keyword}
, а не %keyword%
Ответ 8
Этот подход генерирует шаблоны функций, которые можно кэшировать:
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'
}
});
возвращает:
"Hi John,
Lorem ipsum dolor sit amet...
Best Regarts,
William"
Ответ 9
Mustachejs отлично подходит для действительно элегантных шаблонов:
<div id='sample'>
<h4>{{TITLE}}</h4>
<p>Text text {{KEYWORD}} text</p>
<p>{{CONTENT}}</p>
<img src="images/{{ID}}/1.jpg" />
</div>
Затем вы можете использовать шаблон примерно так:
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;
Это особенно хорошо работает, если вы получаете JSON от вызова Ajax - вы можете просто передать его прямо в вызов Mustache.render()
.
Небольшие вариации позволяют запускать один и тот же шаблон для каждого браузера или сервера. Подробнее см. https://github.com/janl/mustache.js.
Ответ 10
Попробуйте следующее: http://json2html.com/
Он также поддерживает сложные объекты JSON.
Ответ 11
var template = "<div id='sample'><h4>%VAR%</h4><p>Text text %VAR% text</p><p>%VAR%</p><img src="images/%VAR%/1.jpg" /></div>";
var replace = function(temp,replace){
temp = temp.split('%VAR%');
for(var i in replace){
if(typeof temp[i] != 'undefined'){
temp[i] = temp[i] + replace[i];
}
}
return temp.join('');
}
replace(template,['title','keyword','content','id'])