解析时,jQuery 会忽略任何不是表格的内容,并且文档会删除表格标签
Posted
技术标签:
【中文标题】解析时,jQuery 会忽略任何不是表格的内容,并且文档会删除表格标签【英文标题】:When parsing, jQuery ignores anything that isn't a table and document removes the table tag 【发布时间】:2018-06-04 20:26:30 【问题描述】:不确定这是错误还是功能。使用表格外的表格元素解析 html 时,jQuery 会忽略非表格元素。
<tr><td>table data</td></tr>
<div>div after will be ignored</div>
传入$(html)
变成
<tr><td>table data</td></tr>
当将相同的 html 传递给纯 javascript 时,element.innerHTML = html
变为
table data
<div>div after will be ignored</div>
它正在行动https://codepen.io/addbrick/pen/mprBgP
编辑:在发布此内容后,我意识到 jQuery 正在删除表格元素,因为 dom 中的行为相反。
【问题讨论】:
【参考方案1】:首先,这不是一个有效的 HTML。
是的。 Jquery 解析器清理了那个。
如果您仔细查看source code jquery,html 函数会在实际设置innerHTML
之前使用 parseHTML。
而 parseHTML 正在调用 buildFragment 并删除字符串中的所有虚假元素。
下面是buildFragment函数的部分源码
// Add nodes directly
if ( jQuery.type( elem ) === "object" )
jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
// Convert non-html into a text node
else if ( !rhtml.test( elem ) )
nodes.push( context.createTextNode( elem ) );
// Convert html into DOM nodes
else
tmp = tmp || safe.appendChild( context.createElement( "div" ) );
// Deserialize a standard representation
tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
wrap = wrapMap[ tag ] || wrapMap._default;
tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
// Descend through wrappers to the right content
j = wrap[ 0 ];
while ( j-- )
tmp = tmp.lastChild;
// Manually add leading whitespace removed by IE
if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) )
nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[ 0 ] ) );
// Remove IE's autoinserted <tbody> from table fragments
if ( !support.tbody )
// String was a <table>, *may* have spurious <tbody>
elem = tag === "table" && !rtbody.test( elem ) ?
tmp.firstChild :
// String was a bare <thead> or <tfoot>
wrap[ 1 ] === "<table>" && !rtbody.test( elem ) ?
tmp :
0;
是的,这是您实际传递的字符串被评估并创建 DOM 节点的地方。
最后,div 不应该直接用作表格内的元素。可以包裹在td
和tr
中。
那么为什么 jquery 完全忽略了它?因为那不是真实有效的html。如果您仔细查看html specification of Table,您只能拥有给定的标签。在表格标签中,
<!ELEMENT TABLE - -
(CAPTION?, (COL*|COLGROUP*), THEAD?, TFOOT?, TBODY+)>
<!ATTLIST TABLE -- table element --
%attrs; -- %coreattrs, %i18n, %events --
summary %Text; #IMPLIED -- purpose/structure for speech output--
width %Length; #IMPLIED -- table width --
border %Pixels; #IMPLIED -- controls frame width around table --
frame %TFrame; #IMPLIED -- which parts of frame to render --
rules %TRules; #IMPLIED -- rulings between rows and cols --
cellspacing %Length; #IMPLIED -- spacing between cells --
cellpadding %Length; #IMPLIED -- spacing within cells --
>
在每个标签里面
<!ELEMENT THEAD - O (TR)+ -- table header -->
<!ELEMENT TFOOT - O (TR)+ -- table footer -->
如您所见,没有直接允许使用 div 标签。
但是,在 vanilla javascript innerHTML
的情况下,不会发生这样的解析,浏览器会直接解释提供给 dom 节点的字符串并将它们添加到文档中。
删除元素的所有子元素,解析内容字符串并将结果节点分配为元素的子元素。
【讨论】:
以上是关于解析时,jQuery 会忽略任何不是表格的内容,并且文档会删除表格标签的主要内容,如果未能解决你的问题,请参考以下文章