Подтвердить что ты не робот

Эффективная замена строки 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 секунды.

Спасибо заранее.

4b9b3361

Ответ 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'])