javascript - 使用 JavaScript,如何将 HTML 字符串转换为 HTML 标记和文本内容的数组?

标签 javascript html domparser

我有一个 HTML 字符串,例如:

<p>
    <strong><em>Lorem Ipsum </em></strong>is simply dummy text of the printing <em>and</em> typesetting industry.
</p>

我想将其转换成如下所示的 JavaScript 数组:

['<p>', '<strong>', '<em>', 'Lorem Ipsum ', '</em>', '</strong>', 'is simply dummy text of the printing ', '<em>', 'and', '</em>', 'typesetting industry.', '</p>']

即它获取 HTML 字符串并将其分解为一组标签和 HTML 内容。

我已尝试根据 this 使用 DomParser()问题:

const str = `<p><strong><em>Lorem Ipsum </em></strong>is simply dummy text of the printing <em>and</em> typesetting industry.</p>`;

const doc = new DOMParser().parseFromString(str, 'text/html');
const arr = [...doc.body.childNodes]
  .map(child => child.outerHTML || child.textContent);

但是,这只会返回:

['<p><strong><em>Lorem Ipsum </em></strong>is simply dummy text of the printing <em>and</em> typesetting industry.</p>']

我也曾尝试搜索各种基于 Regex 的解决方案,但未能找到任何能够完全按照我的要求分解字符串的解决方案。

有什么建议吗?

谢谢

最佳答案

我会创建一个递归函数来遍历给定节点并返回其子节点的文本表示数组:

const str = `<p><strong><em>Lorem Ipsum </em></strong>is simply dummy text of the printing <em>and</em> typesetting industry.</p>`;

const doc = new DOMParser().parseFromString(str, 'text/html');
const parseNode = node => {
  const output = [];
  for (const child of node.childNodes) {
    if (child.nodeType === Node.TEXT_NODE) {
      output.push(child.textContent);
    } else if (child.nodeType === Node.ELEMENT_NODE) {
      output.push(`<${child.tagName}>`);
      output.push(...parseNode(child));
      output.push(`</${child.tagName}>`);
    }
  }
  return output;
};
console.log(parseNode(doc.body));

如果你也需要保留属性,你可以使用 outerHTML元素的前导非括号:

const str = `<p style="color:green"><strong><em>Lorem Ipsum </em></strong>is simply dummy text of the printing <em>and</em> typesetting industry.</p>`;

const doc = new DOMParser().parseFromString(str, 'text/html');
const parseNode = node => {
  const output = [];
  for (const child of node.childNodes) {
    if (child.nodeType === Node.TEXT_NODE) {
      output.push(child.textContent);
    } else if (child.nodeType === Node.ELEMENT_NODE) {
      const attribs = child.outerHTML.match(/<\s*[^>\s]+([^>]*)/)[1];
      output.push(`<${child.tagName}${attribs}>`);
      output.push(...parseNode(child));
      output.push(`</${child.tagName}>`);
    }
  }
  return output;
};
console.log(parseNode(doc.body));

如果需要自闭标签不展开,检查outerHTML是否元素包含 </ :

const str = `<p style="color:green"><input readonly value="x"/><strong><em>Lorem Ipsum </em></strong>is simply dummy text of the printing <em>and</em> typesetting industry.</p>`;

const doc = new DOMParser().parseFromString(str, 'text/html');
const parseNode = node => {
  const output = [];
  for (const child of node.childNodes) {
    if (child.nodeType === Node.TEXT_NODE) {
      output.push(child.textContent);
    } else if (child.nodeType === Node.ELEMENT_NODE) {
      const attribs = child.outerHTML.match(/<\s*[^>\s]+([^>]*)/)[1];
      output.push(`<${child.tagName}${attribs}>`);
      if (child.outerHTML.includes('</')) {
        // Not self closing:
        output.push(...parseNode(child));
        output.push(`</${child.tagName}>`);
      }
    }
  }
  return output;
};
console.log(parseNode(doc.body));

关于javascript - 使用 JavaScript,如何将 HTML 字符串转换为 HTML 标记和文本内容的数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65572913/

相关文章:

javascript - Angular force 在 url 中出现不需要的感叹号

javascript - d3js 只更新一次

javascript - 提取Id的多个元素jQuery

angular - DOMParser Typescript- 解析 HTML

javascript - 用于 Javascript 的开放 XML SDK

javascript - 使用 JavaScript 启动 CSS-Transition

html - 表格单元格自动换行不适用于斜线

javascript - 在 <body> 中按顺序加载 Javascript 文件并在完成时触发回调

Java DOM 解析器返回空文档

javascript - DOMParser 将 &lt;script&gt; 标签附加到 <head>/<body> 但不执行