【问题标题】:Is there any alternative to innerHTML with .replace() method?使用 .replace() 方法可以替代 innerHTML 吗?
【发布时间】:2021-11-16 14:15:06
【问题描述】:

我知道使用innerHTML 的缺点。但在我的情况下,innerHTML 看起来是不可避免的。要么是不必要的复杂,要么是不可能的(我不这么认为......)

这是我的代码:

function identifier(reg, className) {
  const regex = new RegExp(reg, "gi");
  const p2 = document.querySelectorAll("p");
  p2.forEach((ps) => {
    ps.innerHTML = ps.innerHTML.replace(
      regex,
      (match) => `<span class="${className}">${match}</span>`
    );
  });
}
identifier("[^<>]+?:", "identifier");

在不使用innerHTML 的情况下,还有其他更安全的方法吗?

提前致谢!

编辑:p 元素开头不包含任何其他标签。它只包含文本。但是我想用上面的函数给它添加spans

在此我使用 RegExp 和 replace() 方法将所有标识符(例如:姓名、电子邮件)设置为 span 以分别进行样式设置。像 John Doe 这样的值没有样式化。

【问题讨论】:

  • 我想不出一个简单的方法来做到这一点。您必须为匹配项周围的文本部分创建新的文本节点,然后为匹配项创建跨度节点。
  • 如果段落中已经有 HTML 标签,您将不得不浏览它们。
  • 我认为您可以通过遍历不在标签内的文本节点来做到这一点。
  • 我的第一个想法:为什么会在 JavaScript 中发生这种情况?这看起来像是在生成原始 HTML(即服务器端)时应该做的事情。但除此之外,您的代码缺少太多上下文,无法给出一个好的答案。当然,对于任何可能的 HTML 内容,如果没有 innerHTML 也可以做到这一点,但如果实现可以限制在特定场景中,例如匹配总是在不包含任何其他 HTML 的段落。
  • “要了解我真正打算做什么,请看这支笔(注意它会改变)” - 最后一部分就是为什么你不应该 仅通过外部平台提供相关信息。您的问题的minimal reproducible example 直接属于您的问题。

标签: javascript innerhtml dom-manipulation regexp-replace


【解决方案1】:

有了您的附加信息,这相对容易:

p2.forEach((ps) => {
  // Get text of paragraph removing any HTML
  const text = ps.textContent;

  // Look for colon      
  const colon = text.indexOf(':');
  
  // Skip if there is no colon
  if (colon === -1) {
    return;
  }

  // Delete content of paragraph
  while (ps.lastChild) {
    ps.removeChild(ps.lastChild);
  }

  // Extract texts before (and including) colon and after colon
  const labelText = text.substring(0, colon + 1);
  const otherText = text.substring(colon + 1);

  // Create span with text before colon
  const label = document.createElement('span');
  label.className = className;
  label.appendChild(document.createTextNode(labelText));

  // Create new text node with text after colon
  const otherTextNode = document.createTextNode(otherText);

  // Add both as new children of the paragraph
  ps.appendChild(label);
  ps.appendChild(otherTextNode);
});

当然比使用innerHTML要长,因为我们基本上是在重写正则表达式和浏览器的HTML解析器正在做的事情。

【讨论】:

    猜你喜欢
    • 2014-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-05
    • 2015-05-09
    • 2019-08-10
    • 1970-01-01
    相关资源
    最近更新 更多