解析时,jQuery会忽略任何不是表的内容,而文档会删除表标记

问题描述 投票:10回答:1

不确定这是一个错误还是一个功能。在使用表外的表元素解析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中的相反行为。

javascript jquery dom html-table
1个回答
4
投票

首先,这不是一个有效的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不应该直接在表中使用一个元素。可以包裹在tdtr内。

那么为什么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节点的字符串并将它们添加到文档中。

删除所有元素的子节点,解析内容字符串并将结果节点指定为元素的子节点。

© www.soinside.com 2019 - 2024. All rights reserved.