【问题标题】:javascript replace method works except when in loop it escapes htmljavascript替换方法有效,除非在循环中它转义html
【发布时间】:2017-07-19 14:33:37
【问题描述】:

这段代码可以完美地用一些 html 替换字符串:

$('.active_admin_comment_body').each(function(comment_index){
    the_string = $(this).text().replace("#Excitement", "<span style=\"background-color: lightgrey;\">#Excitement</span>");
     $(this).html(the_string);
)};

上面代码的问题是它只能替换一个值。我有一个值数组,所以我编写了以下代码来循环遍历数组,然后使用数组中的值修改每个注释:

$('.active_admin_comment_body').each(function(comment_index){
    hashtags = ["#Excitement", "#Sad News", "#Moderate"];
    comment = $(this);
    $.each(hashtags, function(index, value){
        new_comment = comment.text().replace(value, "<span style='background-color: lightgrey;'>" + value + "</span>");
        comment.html(new_comment);
    });
});

第一个代码块 100% 工作。仅当您删除 replace 方法中的 html 时,第二个代码块才有效。如何让第二个代码块工作?

【问题讨论】:

  • 如果要替换所有匹配项,请使用str.replace(/textToReplace/g, 'replaceWith');
  • 谢谢,但我不确定我是否理解您的评论。我尝试用replaceWith 切换replace,但没有任何改变。我还查看了replaceWith 的文档,这似乎是针对 DOM 元素,而不是特定文本。
  • @Philip7899 这不是@YordanNikolov 所说的。他指出您应该将"#Excitement" 更改为/#Excitement/gRegExp("#Excitement", "g")g 表示替换所有实例而不是替换第一个然后停止。
  • 冒着给出一个混蛋答案的风险,正确的解决方案是放弃你的代码并使用模板引擎。
  • 我觉得comment.text().replace...应该改成comment.html().replace...。看我的回答。

标签: javascript jquery replace html-escape-characters


【解决方案1】:

罪魁祸首是text() 方法。当你调用它时,它只返回元素内的文本,无意中撤消了任何已经放入的 HTML。

$('.active_admin_comment_body').each(function(comment_index){
    var hashtags = ["#Excitement", "#Sad News", "#Moderate"];
    var comment = $(this);
    $.each(hashtags, function(index, value){
        // I changed text() to html() in the next line.
        var new_comment = comment.html().replace(value, "<span style='background-color: lightgrey;'>" + value + "</span>");
        comment.html(new_comment);
    });
});

您还应该注意,replace 只会替换第一个匹配项。例如,"foo bar foo".replace("foo", "baz") 返回"baz bar foo";你可以看到只替换了第一个foo。如果要替换所有实例,需要指定g 选项; "foo bar foo".replace(RegExp("foo", "g"), "baz") 返回 "baz bar baz"。在您的代码中:

$('.active_admin_comment_body').each(function(comment_index){
    var hashtags = ["#Excitement", "#Sad News", "#Moderate"];
    var comment = $(this);
    $.each(hashtags, function(index, value){
        // I changed text() to html() and added the RegExp constructor.
        var new_comment = comment.html().replace(RegExp(value, "g"), "<span style='background-color: lightgrey;'>" + value + "</span>");
        comment.html(new_comment);
    });
});

如果您将hashtags 中的项目更改为包含不是主题标签的字符串,您可能需要使用\ 转义某些字符,以便它们不会被解释为特殊字符。有关需要转义的字符表,请参阅 this link# 符号不是特殊字符之一,因此如果您只使用主题标签,则无需担心。

最后,您可能希望使用回调替换,而不是使用循环来更改多个字符串:

$('.active_admin_comment_body').each(function(comment_index){
    var hashtags = ["#Excitement", "#Sad News", "#Moderate"];
    var comment = $(this);
    var new_comment = comment.html().replace(/#(Excitement|Sad News|Moderate)/g, function(tag){
        return "<span style='background-color: lightgrey;'>" + tag + "</span>";
    });
    comment.html(new_comment);
});

您还会注意到我在您的代码中添加了var 关键字;这使您的变量成为局部变量而不是全局变量。这不会改变代码的功能。

【讨论】:

    【解决方案2】:

    使用 html(function)new RegExp() 加入数组,使用 | 进行 OR

    var hashtags = ["#Excitement", "#Sad News", "#Moderate"];
    
    $('.active_admin_comment_body').html(function(_, txt) {
      var reg = new RegExp('(' + hashtags.join('|') + ')', 'g');
      return txt.replace(reg, '<span class="lightgrey">$1</span>');
    });
    .lightgrey{
      background-color: lightgrey;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class='active_admin_comment_body'>
      Test1 #Excitement
    </div>
    <div class='active_admin_comment_body'>
      Test2 #Sad News
    </div>
    <div class='active_admin_comment_body'>
      Test3 #Moderate
    </div>

    【讨论】:

      【解决方案3】:

      看起来你实际上只是错过了一件小事。您循环的工作方式只是替换数组中的最后一个。更改数组中的最后一个值会导致它切换哪个正在工作。

      刚刚将主题标签与当前字符串匹配,一切正常。

      唯一添加到代码中的是 if 语句,用于比较匹配。

      $(function(){
      $('.active_admin_comment_body').each(function(comment_index){
          hashtags = ["#Excitement", "#Sad News", "#Moderate"];
          comment = $(this);
          $.each(hashtags, function(index, value){
          	if(comment.text().includes(value)){
            	new_comment = comment.text().replace(value, "<span style='background-color: lightgrey;'>" + value + "		</span>");
              comment.html(new_comment);
            }
          });
      });
      });
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <div class='active_admin_comment_body'>
      Test1 #Excitement
      </div>
      <div class='active_admin_comment_body'>
      Test2 #Sad News
      </div>
      <div class='active_admin_comment_body'>
      Test3 #Moderate
      </div>

      https://jsfiddle.net/75e0o36s/

      【讨论】:

        【解决方案4】:

        textToReplace 是 "#Excitement" & replaceWith 是 "&lt;span style=\"background-color: lightgrey;\"&gt;#Excitement&lt;/span&gt;" 在你的情况下它会变成

        the_string = $(this).text().replace(/#Excitement/g, "<span style=\"background-color: lightgrey;\">#Excitement</span>");
        
        new_comment = comment.text();
        $.each(hashtags, function(index, value){
                new_comment = new_comment.replace(value, "<span style='background-color: lightgrey;'>" + value + "</span>");
            });
        comment.html(new_comment);
        

        更新

        【讨论】:

        • 谢谢,但我已经用 #excitement 让它工作了。我正在尝试让第二个代码块在您循环遍历数组的地方工作
        猜你喜欢
        • 2012-09-20
        • 2022-06-14
        • 2011-01-11
        • 2021-03-17
        • 2016-08-25
        • 1970-01-01
        • 2011-03-02
        • 1970-01-01
        • 2017-02-28
        相关资源
        最近更新 更多