无法创建存储td,tr或th的DocumentFragment?

时间:2017-03-29 19:54:31

标签: javascript html documentfragment html5-template

是否可以让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。

由于

3 个答案:

答案 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;首先用正确的父标签包装它,然后将你想要的节点添加到文档片段(没有临时父节点)。

你会像这样使用它:

&#13;
&#13;
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;
&#13;
&#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)
}