我有一个表示元素的HTML字符串:“<li>text</li>”。我想将它附加到DOM中的一个元素(在我的例子中是一个ul)。如何使用Prototype或DOM方法做到这一点?
(我知道我可以在jQuery中轻松做到这一点,但不幸的是,我们没有使用jQuery。)
我有一个表示元素的HTML字符串:“<li>text</li>”。我想将它附加到DOM中的一个元素(在我的例子中是一个ul)。如何使用Prototype或DOM方法做到这一点?
(我知道我可以在jQuery中轻松做到这一点,但不幸的是,我们没有使用jQuery。)
当前回答
较新的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
其他回答
对于某些html片段,如<td>test</td>、div.innerHTML、DOMParser.parseFromString和range.createContextualFragment(没有正确的上下文),此处其他答案中提到的解决方案不会创建<td>元素。
jQuery.parseHTML()正确处理它们(我将jQuery2的parseHTML函数提取为一个独立函数,可以在非jQuery代码库中使用)。
如果您只支持Edge 13+,那么只使用HTML5模板标记会更简单:
function parseHTML(html) {
var t = document.createElement('template');
t.innerHTML = html;
return t.content;
}
var documentFragment = parseHTML('<td>Test</td>');
HTML5引入了可用于此目的的<template>元素(如现在在WhatWG规范和MDN文档中所描述的)。
<template>元素用于声明可在脚本中使用的HTML片段。元素在DOM中表示为HTMLTemplateElement,该元素具有DocumentFragment类型的.content属性,以提供对模板内容的访问。这意味着您可以通过设置<template>元素的innerHTML,然后到达模板的.content属性,将HTML字符串转换为DOM元素。
示例:
/**
* @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对允许哪些元素类型存在于哪些其他元素类型中有限制;例如,不能将td作为div的直接子级。如果试图将div的innerHTML设置为包含这些元素,这会导致这些元素消失。由于<template>对其内容没有这样的限制,因此在使用模板时不适用此缺点。
然而,一些旧浏览器不支持模板。截至2021 4月,我可以使用……吗。。。据估计,全球96%的用户正在使用支持模板的浏览器。特别是,没有版本的Internet Explorer支持它们;在Edge发布之前,Microsoft没有实施模板支持。
如果你有幸编写了只针对现代浏览器用户的代码,那么现在就开始使用吧。否则,您可能需要等待一段时间才能让用户跟上。
注意:大多数当前浏览器都支持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模板不同,这对于某些不能合法成为<div>的子元素的元素(如<td>s)不起作用。
如果您已经在使用一个库,我建议您坚持使用库批准的方法,从HTML字符串创建元素:
原型在其update()方法中内置了此功能。jQuery在其jQuery(html)和jQuery.parseHTML方法中实现了它。
以下是如何使用PrototypeJS(正如OP 12年前最初要求的那样):
HTML格式:
<ul id="mylist"></ul>
JS:
$('mylist').insert('<li>text</li>');
注意,这不是jQuery!
答复
创建模板将模板的innerHTML设置为strim.trim()创建模板的子级数组返回子项、子项或
函数toElement(s=“”,c,t=document.createElement('template'),l='length'){t.innerHTML=s.trim();c=[…t.content.childNodes];返回c[l]>1?c: c[0]| |“”;}console.log(toElement());console.log(toElement(“”));console.log(toElement(“”));console.log(toElement('<td>With td</td>'));console.log(toElement('<tr><td>With t</td></tr>'));console.log(toElement('<tr><td>foo</td></tr><tr><td>bar</td></tr>'));console.log(toElement('<div><span><span>嵌套</span><span>填充</span></div>'));