代码之家  ›  专栏  ›  技术社区  ›  AvcS

如何检测内存中的DOM元素是否是块元素?

  •  0
  • AvcS  · 技术社区  · 5 年前

    我有一些HTML作为字符串,我需要将所有内联元素包装在 p 标记,而不实际呈现它们。

    例子:

    <h2>Some heading</h2>
    <p>Some content</p>
    <strong>Some inline content</strong>
    

    应转换为

    <h2>Some heading</h2>
    <p>Some content</p>
    <p><strong>Some inline content</strong></p>
    

    我正在通过创建内存中的DOM来处理HTML。

    function ensureRootLevelBlockTags(html) {
        const psuedoDom = document.createElement('div');
        psuedoDom.innerHTML = html;
    
        const childNodes = psuedoDom.childNodes;
        for (let i = 0; i < childNodes.length; i++) {
            const currentNode = childNodes[i];
            if (/* is currentNode is not a block element */) {
                const newNode = document.createElement('p');
                newNode.append(currentNode);
                psuedoDom.insertBefore(newNode, childNodes[i]);
            }
        }
    
        return psuedoDom.innerHTML;
    }
    
    ensureRootLevelBlockTags('<h2>Some heading</h2><p>Some content</p><strong>Some inline content</strong>');
    

    我需要可以用来检查元素是否是块元素的条件。

    编辑:

    我们已经在项目中使用Tinymce,发现 tinymce.html.Schema 对象包含有效标记及其有效子代的列表。最后我用它作为参考来检查是否可以将元素包装在 .

    3 回复  |  直到 5 年前
        1
  •  1
  •   T.J. Crowder    5 年前

    我不认为你真的在寻找“块”元素(这部分是基于你对我的错误-现在删除-答案的评论)。据我所知,您正在寻找的顶级元素只能出现在 phrasing-content >a>中,并且您希望将它们包装在可以出现在 flow 内容

    但是关于内容类别的问题是,大多数短语内容也是完全有效的流内容;从 kinds of content in the spec:。

    我看到执行您描述的操作的唯一方法是硬编码仅使用短语的元素类型列表,并在循环中对照该列表检查标记名。

    该列表当前为:

    • A
    • abbr
    • area (如果它是地图元素的后代)
    • audio
    • b
    • bdi
    • bdo
    • br
    • button
    • canvas
    • cite
    • code
    • data
    • datalist
    • del
    • dfn
    • em
    • embed
    • i
    • iframe
    • img
    • input
    • ins
    • kbd
    • label
    • link (如果车身中允许这样做)
    • map
    • mark
    • math (mathml)
    • meta (如果存在itemprop属性)
    • meter
    • noscript
    • object
    • output
    • picture
    • progress
    • q
    • ruby
    • s
    • samp
    • script
    • 选择
    • slot
    • small
    • span
    • strong
    • sub
    • sup
    • svg (svg)
    • template
    • textarea
    • time
    • u
    • var
    • video
    • wbr

    您可能会忽略其中的一些内容(例如 link )。

    但同样,它们是有效的流内容,因此不必包装它们。

    告诉你,你正在寻找只能出现在 phrasing content 你想把它们包起来 flow content .

    但是,关于内容类别的问题是,大多数短语内容也是完全有效的流内容;来自 Kinds of Content 在规范中:

    enter image description here

    我看到执行您描述的操作的唯一方法是硬编码只使用短语的元素类型列表,并在循环中对照该列表检查标记名。

    该列表当前为:

    • a
    • abbr
    • area (如果它是映射元素的后代)
    • audio
    • b
    • bdi
    • bdo
    • br
    • button
    • canvas
    • cite
    • code
    • data
    • datalist
    • del
    • dfn
    • em
    • embed
    • i
    • iframe
    • img
    • input
    • ins
    • kbd
    • label
    • link (如果允许进入身体)
    • map
    • mark
    • math (MATML)
    • meta (如果存在itemprop属性)
    • meter
    • noscript
    • object
    • output
    • picture
    • progress
    • q
    • ruby
    • s
    • samp
    • script
    • select
    • slot
    • small
    • span
    • strong
    • sub
    • sup
    • svg (SVG)
    • template
    • textarea
    • time
    • u
    • var
    • video
    • wbr

    你可以省略其中的一些(例如 链接 )

    但同样,它们是有效的流内容,因此不需要包装它们。

        2
  •  1
  •   Nikos M.    5 年前

    使用 element tagName property 检查节点/元素是否是块级元素(例如 https://www.google.com/search?q=html+block+elements&ie=utf-8&oe=utf-8&client=firefox-b 将以下元素作为块级别提供)

    • P.
    • h1、h2、h3、h4、h5、h6。
    • 欧拉,欧拉。
    • 之前。
    • 地址。
    • 块引用。
    • DL
    • div

    所以像下面这样的事情应该做:

    const BLOCK_LEVEL = {'DIV':1, 'DL':1, 'BLOCKQUOTE':1 /*, ..*/};
    // rest code here
    const currentNode = childNodes[i];
       if (currentNode.tagName && BLOCK_LEVEL[currentNode.tagName]) {
           // is block-level element, handle accordingly
       }
    
        3
  •  -1
  •   bluninja1234 vassiliskrikonis    5 年前

    尝试使用 node.style.display 元素。结果要么是 block , inline , none inline-block .