【问题标题】:convert string that contains <,> (Special chars) to html将包含 <,> (特殊字符)的字符串转换为 html
【发布时间】:2019-05-02 06:39:45
【问题描述】:

我有一个字符串,即&lt;some text&gt;
我正在尝试使用替换功能突出显示其中的“te”

 InnerHTML = innerHTML.replace(some_Regex_Pattern['te'], '<span style=\'background-color:#FFFB00\'>$&</span>');

我得到的字符串是,

<some <span class=\'highlight\' style=\'background-color:#FFFB00\'>te</span>xt>

现在将此设置为 element.innerHTML,被视为 HTML 标记,导致问题。
在 DOM 中,我将元素作为

<some <span class=\'highlight\' style=\'background-color:#FFFB00\'>te</span>xt></some>

我得到格式错误的字符串,如何将其转换为正确的格式,而不更改正确的 html 标记,即此处?

我该如何解决这个问题,..如果不能理解,请评论,..

【问题讨论】:

  • 你获取的字符串不是有效的html,格式错误。以 .... 结尾。 ???
  • 是的,完全正确,.. 我得到格式错误的字符串,如何将其转换为正确的格式,而不更改正确的 html 标记,即此处的

标签: javascript html typescript browser replace


【解决方案1】:

在替换 te 之前,您必须将 &amp;lt; 替换为 &amp;lt; 并将 &amp;gt; 替换为 &amp;gt;

innerHTML.replace('<', '&lt;').replace('>', '&gt;')...

【讨论】:

    【解决方案2】:

    Regular expressions and HTML don't mix very well。在您的情况下,如果您非常小心,您可以手动转义所有正确的值并生成有效的 HTML。如果您甚至有点粗心,您就会遇到格式错误或不安全的内容的问题。这并不是说“你绝对不能那样做”,但你至少应该意识到这样做所涉及的陷阱。

    推荐的解决方案是永远不要自己以编程方式操作 HTML 字符串。相反,您应该操纵 HTMLElement objects 并信任您的 JavaScript 引擎来处理 HTML。

    在您的情况下,我想说这个问题有两个组成部分。

    一:将字符串转换为字符串的片段被标记为“应该突出显示”或“不应该突出显示”的表示形式。如果你引入如下接口(毕竟你使用了 TypeScript 标签):

    interface HighlightableString {
        value: string;
        highlighted: boolean;
    }
    

    然后,带有突出显示部分的字符串可以表示为Array&lt;HighlightableString&gt;

    所以你需要一个函数来将"&lt;some text&gt;" 之类的字符串和"te" 之类的子字符串转换为类似

    [ 
      {value: "<some ", highlighted: false}, 
      {value: "te", highlighted: true}, 
      {value: "xt>", highlighted: false}
    ]
    

    这是该功能的一种可能实现方式,但您可以按照自己的意愿进行操作。这是使用正则表达式的绝佳场所,因为这里无法表示“不安全”或“格式错误”的 HTML:

    function highlightSubstring(s: string, substring: string): Array<HighlightableString> {
        if (substring.length === 0) return [{ value: s, highlighted: false }]
        const ret: Array<HighlightableString> = [];
        for (
          var prevPos = 0, pos = s.indexOf(substring); 
          pos >= 0; 
          prevPos = pos + substring.length, pos = s.indexOf(substring, prevPos)
        ) {
            ret.push({ value: s.substring(prevPos, pos), highlighted: false });
            ret.push({ value: substring, highlighted: true });
        }
        ret.push({ value: s.substring(prevPos), highlighted: false });
        return ret;
    }
    

    两个:给定一个Array&lt;HighlightableString&gt;,一个父HTMLElement,以及一些突出显示文本的方式(例如,一个代表这种突出显示的HTMLElement),将正确突出显示的文本添加到该父元素。这是您根本不想使用正则表达式或 HTML 文本的地方。这是一种可能的实现方式:

    function appendHighlightedString(
      highlightableStrings: Array<HighlightableString>, 
      parentElement: HTMLElement, 
      highlightElement: HTMLElement
    ) {
      highlightableStrings.forEach(hs => {
        const textNode = document.createTextNode(hs.value);
          if (hs.highlighted) {
              const highlightClone = highlightElement.cloneNode(true);
              highlightClone.appendChild(textNode)
              parentElement.appendChild(highlightClone)
          } else {
              parentElement.appendChild(textNode);
          }
      })
    }
    

    注意该函数是如何使用Text 节点以及元素克隆和附加的。它从不直接查看 HTML。

    好的,让我们看看它是否有效。我会试试&lt;test content&gt;的内容:

    // make a highlight element
    const highlightElement = document.createElement("span");
    highlightElement.style.backgroundColor = '#FFFB00';
    
    const wholeString = document.createElement("div"); // or whatever the parent element is
    appendHighlightedString(
      highlightSubstring("<test content>", "te"), 
      wholeString, 
      highlightElement
    );
    

    让我们看看它在 Firefox 中做了什么:

    console.log(wholeString.innerHTML);
    // &lt;<span style="background-color: rgb(255, 251, 0);">te</span>st 
    // con<span style="background-color: rgb(255, 251, 0);">te</span>nt&gt;
    

    好吧,浏览器决定使用rgb(255, 251, 0) 而不是#FFFB00。但那是浏览器的特权;我们退出了 HTML 游戏。关键是如果您将该元素添加到文档中,

    document.body.appendChild(wholeString);
    

    它将以您想要的方式突出显示。

    好的,希望对您有所帮助。祝你好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-25
      • 2013-03-08
      • 1970-01-01
      • 1970-01-01
      • 2012-05-01
      • 2011-08-09
      • 2015-02-20
      • 2019-02-17
      相关资源
      最近更新 更多