admin管理员组文章数量:1431720
Is it possible to have DocumentFragments contain tr, th or td tags?
If I do this:
var template = document.createRange().createContextualFragment(
'<table></table>'
);
console.log(template.childNodes);
I get the output of [table]
.
If I do this:
var template = document.createRange().createContextualFragment(
'<td></td>'
);
console.log(template.childNodes);
I get the output of []
!!!?!?
If I do this:
var template = document.createRange().createContextualFragment(
'<td><p></p></td>'
);
console.log(template.childNodes);
I get [p]
??!?!?!??!?!??!
And finally if I do this:
var template = document.createRange().createContextualFragment(
'<span><td></td></span>'
);
console.log(template.childNodes);
I get [span]
- where's the td gone??!
I don't understand the inconsistency here. Is it possible for document fragments to only hold certain elements? What I would like to do is do something akin to the second this above, and then retrieve the td using querySelector
.
Thanks
Is it possible to have DocumentFragments contain tr, th or td tags?
If I do this:
var template = document.createRange().createContextualFragment(
'<table></table>'
);
console.log(template.childNodes);
I get the output of [table]
.
If I do this:
var template = document.createRange().createContextualFragment(
'<td></td>'
);
console.log(template.childNodes);
I get the output of []
!!!?!?
If I do this:
var template = document.createRange().createContextualFragment(
'<td><p></p></td>'
);
console.log(template.childNodes);
I get [p]
??!?!?!??!?!??!
And finally if I do this:
var template = document.createRange().createContextualFragment(
'<span><td></td></span>'
);
console.log(template.childNodes);
I get [span]
- where's the td gone??!
I don't understand the inconsistency here. Is it possible for document fragments to only hold certain elements? What I would like to do is do something akin to the second this above, and then retrieve the td using querySelector
.
Thanks
Share Improve this question edited Dec 4, 2017 at 19:11 Supersharp 31.3k11 gold badges102 silver badges147 bronze badges asked Mar 29, 2017 at 19:54 Raiden616Raiden616 1,5643 gold badges19 silver badges46 bronze badges 3-
Why are you using
document.createRange()…
and not justdocument.createDocumentFragment()
? The later can contain just<td>
s perfectly well. – Matijs Commented Mar 29, 2017 at 20:02 - I wasn't awRe there was a difference to be honest.. I was using the former to allow me to specify xhtml direct. Is there a way of doing that with the latter method? – Raiden616 Commented Mar 29, 2017 at 20:15
- @Matijs I just tried it with createDocumentFragment() and get the same result... – Raiden616 Commented Mar 29, 2017 at 20:34
3 Answers
Reset to default 7Solution 1
Use createDocumentFragment(), create a <td>
element, and add it to the DocumentFragment with appendChild()
:
var frag = document.createDocumentFragment()
frag.appendChild( document.createElement( 'td' ) )
console.log( frag.childNodes ) // output => [td]
Solution 2
Create a <template>
element, add HTML content to innerHTML
, then get the DocumentFragment from the content
property:
var template = document.createElement( 'template' )
template.innerHTML = '<td></td>'
var frag = template.content
console.log( frag.childNodes ) // output => [td]
I have written a library for doing just this (creating document fragments from an HTML string). It is called html-fragment
.
This small library attempts to use the range API (as you are doing), but if the top level node is a node that needs a specific parent node (such as a td
), it will attempt to try some other solutions, such as a template
if it is supported, otherwise it does it the "old fashioned way" where it wraps it first with the correct parent tag, and then adds the nodes you wanted to the document fragment (without the temporary parent nodes).
You would use it like so:
var html = '<td><p>Hello World</p></td>';
var fragment = HtmlFragment(html);
console.log(fragment.firstChild) //td
<script src="https://unpkg./[email protected]/lib/html-fragment.min.js"></script>
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/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)
}
本文标签: javascriptCannot create DocumentFragment storing tdtr or thStack Overflow
版权声明:本文标题:javascript - Cannot create DocumentFragment storing td, tr or th? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745579419a2664531.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论