代码之家  ›  专栏  ›  技术社区  ›  Josh

高效的Javascript字符串替换

  •  30
  • Josh  · 技术社区  · 16 年前

    嘿,我有一个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);
    

    提前谢谢。

    11 回复  |  直到 16 年前
        1
  •  88
  •   some    8 年前

    看起来您想要使用一个模板。

    //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 作为现有元素的id。
    • data
    • 使用两个参数替换以执行替换:
    • 第一个是一个regexp,它搜索所有 %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"});
    
        2
  •  29
  •   Sergey Ponomarev Bharat Pahalwani    3 年前

    您可能可以修改此代码以执行您想要的操作:

    let user = {
        "firstName": "John",
        "login": "john_doe",
        "password": "test",
    };
    
    let template = `Hey {firstName},
        
        You recently requested your password.
        login: {login}
        password: {password}
        
        If you did not request your password, please disregard this message.
        `;
    
    template = template.replace(/{([^{}]+)}/g, function(keyExpr, key) {
        return user[key] || "";
    });
    

    JavaScriptTemplates

        3
  •  20
  •   Lior Elrom    3 年前

    Template Replacement

    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);
    
        4
  •  14
  •   Vilx-    16 年前

    我怀疑会有更有效的办法。另一种方法是将其拆分为多个部分,然后进行连接,但我认为这不会有多大的效率。考虑到每次串联都会产生一个与操作数大小相同的新字符串,可能更少。

    补充:

        5
  •  2
  •   orip    16 年前

    您的方法是实现穷人模板系统的标准方法,所以它很好。

    值得您去看看一些JavaScript模板库,例如 JST

        6
  •  1
  •   annakata    16 年前

    您可以通过链接替换而不是进行所有这些临时分配来提高效率。

    with(document.getElementById('sample'))
    {
      innerHTML = innerHTML.replace(a, A).replace(b, B).replace(c, C); //etc
    }
    
        7
  •  1
  •   Kenan Banks    16 年前

    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
  •  1
  •   Jesús Germade    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
  •  0
  •   Philip Callender    10 年前

    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;
    

    如果您从Ajax调用中获取JSON,这一点尤其有效——您可以直接将其传递给 Mustache.render()

    轻微的变化允许在浏览器或服务器上运行相同的模板。看见 https://github.com/janl/mustache.js

        10
  •  0
  •   sura2k    8 年前
        11
  •  -2
  •   garyfunghc    9 年前
    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'])