是否可以让DocumentFragments包含tr,th或td标签?
如果我这样做:
var template = document.createRange().createContextualFragment(
'<table></table>'
);
console.log(template.childNodes);
我得到[table]
的输出。
如果我这样做:
var template = document.createRange().createContextualFragment(
'<td></td>'
);
console.log(template.childNodes);
我得到[]
的输出!!!?!?
如果我这样做:
var template = document.createRange().createContextualFragment(
'<td><p></p></td>'
);
console.log(template.childNodes);
我得到[p]
??!?!?!??!?!??!
最后,如果我这样做:
var template = document.createRange().createContextualFragment(
'<span><td></td></span>'
);
console.log(template.childNodes);
我得到[span]
- td去了哪里?!
我不明白这里的不一致。文档片段是否可能只包含某些元素?我想做的是做类似于上面第二个的事情,然后使用querySelector
检索td。
由于
答案 0 :(得分:3)
解决方案1
使用createDocumentFragement()
,创建一个<td>
元素,然后使用appendChild()
将其添加到DocumentFragment中:
var frag = document.createDocumentFragment()
frag.appendChild( document.createElement( 'td' ) )
console.log( frag.childNodes ) // output => [td]
解决方案2
创建<template>
元素,将HTML内容添加到innerHTML
,然后从content
属性中获取DocumentFragment:
var template = document.createElement( 'template' )
template.innerHTML = '<td></td>'
var frag = template.content
console.log( frag.childNodes ) // output => [td]
答案 1 :(得分:1)
我编写了一个用于执行此操作的库(从HTML字符串创建文档片段)。它被称为html-fragment
。
这个小型库尝试使用范围API(正如您所做),但如果顶级节点是需要特定父节点的节点(例如td
),它将尝试尝试一些其他解决方案,例如template
如果它被支持,否则它会采用老式方式&#34;首先用正确的父标签包装它,然后将你想要的节点添加到文档片段(没有临时父节点)。
你会像这样使用它:
var html = '<td><p>Hello World</p></td>';
var fragment = HtmlFragment(html);
console.log(fragment.firstChild) //td
&#13;
<script src="https://unpkg.com/html-fragment@1.1.0/lib/html-fragment.min.js"></script>
&#13;
答案 2 :(得分:-1)
const range = new Range()
const tableRange = new Range()
const table = document.createElement('table')
const tbody = document.createElement('tbody')
const tr = document.createElement('tr')
const colgroup = document.createElement('colgroup')
/**
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element#Table_content
*/
const tableTags = [
'tbody',
'thead',
'tfoot',
'caption',
'colgroup',
'col',
'tr',
'td',
'th'
]
export function createFragment(str: string) {
const firstTag = str.match(/^<(([a-z]|-)+)/)?.[1]
if (firstTag && tableTags.includes(firstTag)) {
switch (firstTag) {
case 'tbody':
case 'thead':
case 'tfoot':
case 'caption':
case 'colgroup':
tableRange.selectNodeContents(table)
break
case 'tr':
tableRange.selectNodeContents(tbody)
break
case 'td':
case 'th':
tableRange.selectNodeContents(tr)
break
case 'col':
tableRange.selectNodeContents(colgroup)
break
default:
break
}
return tableRange.createContextualFragment(str)
}
return range.createContextualFragment(str)
}