我有一个表示元素的 HTML 字符串:'<li>text</li>'
. 我想将它附加到 DOM 中的一个元素(ul
在我的例子中是一个)。我如何使用 Prototype 或 DOM 方法做到这一点?
(我知道我可以在 jQuery 中轻松做到这一点,但不幸的是我们没有使用 jQuery。)
我有一个表示元素的 HTML 字符串:'<li>text</li>'
. 我想将它附加到 DOM 中的一个元素(ul
在我的例子中是一个)。我如何使用 Prototype 或 DOM 方法做到这一点?
(我知道我可以在 jQuery 中轻松做到这一点,但不幸的是我们没有使用 jQuery。)
注意:当前大多数浏览器都支持 HTML<template>
元素,它提供了一种更可靠的方法来从字符串创建元素。有关详细信息,请参阅下方 Mark Amery 的回答。
对于较旧的浏览器和 node/jsdom :(<template>
在撰写本文时尚不支持元素),请使用以下方法。这与库用来从 HTML 字符串获取 DOM 元素的事情相同(IE需要做一些额外的工作来解决其实现中的错误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 模板不同,这不适用于某些不能合法成为 a 子元素的元素<div>
,例如<td>
s。
如果您已经在使用库,我建议您坚持使用库批准的从 HTML 字符串创建元素的方法:
update()
方法中内置了这个特性。jQuery(html)
和jQuery.parseHTML
方法中实现了它。HTML 5 引入了<template>
可用于此目的的元素(如现在在WhatWG 规范和MDN 文档中所述)。
甲<template>
元件用于声明可以在脚本中使用的HTML的片段。元素在 DOM 中表示为HTMLTemplateElement
具有类型.content
属性的a DocumentFragment
,以提供对模板内容的访问。这意味着,你可以通过设置一个HTML字符串转换为DOM元素innerHTML
a的<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>');
请注意,使用不同容器元素(例如 a)的div
类似方法不太有效。HTML 对哪些元素类型允许存在于哪些其他元素类型中进行了限制;例如,您不能将 atd
作为 a 的直接子代div
。如果您尝试设置innerHTML
adiv
以包含它们,这会导致这些元素消失。由于<template>
s 对它们的内容没有这样的限制,所以在使用模板时这个缺点不适用。
但是,template
在某些旧浏览器中不支持。截至 2021 年 4 月,Can I use...估计全球 96% 的用户正在使用支持template
s的浏览器。特别是,没有任何版本的 Internet Explorer 支持它们;Microsofttemplate
直到 Edge 发布才实施支持。
如果您有幸编写仅针对现代浏览器用户的代码,请立即使用它们。否则,您可能需要等待一段时间才能让用户跟上。
使用insertAdjacentHTML()。它适用于所有当前浏览器,甚至适用于 IE11。
var mylist = document.getElementById('mylist');
mylist.insertAdjacentHTML('beforeend', '<li>third</li>');
<ul id="mylist">
<li>first</li>
<li>second</li>
</ul>
无需任何调整,您就有了一个原生 API:
const toNodes = html =>
new DOMParser().parseFromString(html, 'text/html').body.childNodes[0]
较新的 DOM 实现具有range.createContextualFragment
,它以独立于框架的方式执行您想要的操作。
它得到了广泛的支持。不过可以肯定的是,在同一个 MDN 链接中检查它的兼容性,因为它会发生变化。截至 2017 年 5 月,情况如下:
Feature Chrome Edge Firefox(Gecko) Internet Explorer Opera Safari
Basic support (Yes) (Yes) (Yes) 11 15.0 9.1.2