使用内置的 DOM 方法或原型从 HTML 字符串创建新的 DOM 元素

2022-08-29 22:25:32

我有一个表示元素的HTML字符串:。我想将它附加到DOM中的元素(在我的情况下是a)。如何使用原型或 DOM 方法执行此操作?'<li>text</li>'ul

(我知道我可以在jQuery中轻松做到这一点,但不幸的是我们没有使用jQuery。


答案 1

注意:大多数当前的浏览器都支持HTML元素,它提供了一种更可靠的方法来从字符串创建元素。有关详细信息,请参阅下面Mark Amery的答案<template>

对于较旧的浏览器和 node/jsdom:(在撰写本文时尚不支持元素),请使用以下方法。这与库从HTML字符串中获取DOM元素所做的事情相同(IE需要做一些额外的工作来解决其实现中的错误):<template>innerHTML

function createElementFromHTML(htmlString) {
  var div = document.createElement('div');
  div.innerHTML = htmlString.trim();

  // Change this to div.childNodes to support multiple top-level nodes.
  return div.firstChild;
}

请注意,与 HTML 模板不同,这不适用于某些在法律上不能成为 的子级元素,例如 s。<div><td>

如果您已经在使用库,我建议您坚持使用库批准的从HTML字符串创建元素的方法:


答案 2

HTML 5引入了可用于此目的的元素(如WhatWG规范MDN文档中所述)。<template>

元素用于声明可在脚本中使用的 HTML 片段。该元素在 DOM 中表示为 HTMLTemplateElement,其具有 DocumentFragment 类型的 .content 属性,以提供对模板内容的访问。这意味着您可以通过设置元素的内部HTML,然后进入 的属性,将 HTML 字符串转换为 DOM 元素。<template><template>template.content

例子:

/**
 * @param {String} HTML representing a single element
 * @return {Element}
 */
function htmlToElement(html) {
    var template = document.createElement('template');
    html = html.trim(); // Never return a text node of whitespace as the result
    template.innerHTML = html;
    return template.content.firstChild;
}

var td = htmlToElement('<td>foo</td>'),
    div = htmlToElement('<div><span>nested</span> <span>stuff</span></div>');

/**
 * @param {String} HTML representing any number of sibling elements
 * @return {NodeList} 
 */
function htmlToElements(html) {
    var template = document.createElement('template');
    template.innerHTML = html;
    return template.content.childNodes;
}

var rows = htmlToElements('<tr><td>foo</td></tr><tr><td>bar</td></tr>');

请注意,使用不同容器元素(如 div)类似方法并不完全有效。HTML对允许哪些元素类型存在于哪些其他元素类型中有限制;例如,您不能将 a 作为 的直系子项。如果您尝试将 的 设置 为 包含这些元素,这将导致这些元素消失。由于 s 对其内容没有此类限制,因此在使用模板时不适用此缺点。tddivinnerHTMLdiv<template>

但是,在某些旧浏览器中不受支持。截至2021年4月,我可以使用吗...估计全球96%的用户正在使用支持模板的浏览器。特别是,没有版本的Internet Explorer支持它们;微软直到Edge发布才实施支持。templatetemplate

如果您有幸编写了仅针对现代浏览器用户的代码,请继续立即使用它们。否则,您可能需要等待一段时间才能让用户赶上。