我有一些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
对象包含有效标记及其有效子代的列表。我最终将其用作参考,以检查是否可以将元素包装在p
中。
答案 0 :(得分:1)
使用element tagName
property检查节点/元素是否为块级元素之一(例如https://www.google.com/search?q=html+block+elements&ie=utf-8&oe=utf-8&client=firefox-b将以下元素作为块级元素
所以应该执行以下操作:
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
}
答案 1 :(得分:1)
我认为您并不是要真正寻找“阻止”元素(部分原因是您对我的错误答案(现已删除)做出了评论)。据我所知,您正在寻找仅可以在phrasing content中出现的顶级元素,并且想要将它们包装在可以在flow content中出现的东西中。
但是关于内容类别的事情是,大多数措辞内容也是完全有效的流内容;来自规范中的Kinds of Content:
我看到要执行的操作的唯一方法是对仅短语元素类型的列表进行硬编码,并在循环中对照该列表检查标签名称。
该列表当前为:
a
abbr
area
(如果它是map元素的后代)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
select
slot
small
span
strong
sub
sup
svg
(SVG)template
textarea
time
u
var
video
wbr
您可能会省略其中一些(例如link
)。
但是,它们又是有效的流内容,因此没有必要将它们包装起来。
答案 2 :(得分:-1)
尝试使用node.style.display
元素。结果将为block
,inline
,none
或inline-block
。