我想编写一段代码,以遍历页面的document.body并报告所有空块级DOM节点。这是SEO / a11y的通行证。
我发现这篇文章似乎会有所帮助:
https://css-tricks.com/snippets/jquery/check-for-empty-elements/
$('*').each(function() {
if ($(this).is(':empty') == "") {
//Do Something
}
});
问题#1:如何将.is(':empty')
转换为普通js:
function isEmpty(el) {
// Robust isEmpty logic here
}
document.querySelectorAll('*').filter(el => {
return isEmpty(el);
});
问题2:这个逻辑是否也会遍历所有孩子?
问题3:我们可以仅对块级元素使用此querySelector吗?
答案 0 :(得分:9)
“ {empty”(空)的DOM版本是没有子节点,您可以通过多种方式检查子节点,最常见的两种可能是:
firstChild
将为null
childNodes
中的length
将是0
例如,由于null
是虚假的,而filter
使用的是真实/虚假值:
const allEmpty = [...document.querySelectorAll('*')].filter(el => !el.firstChild);
(请注意,querySelectorAll
返回一个NodeList
,而NodeList
没有一个filter
方法,因此我在此处使用了扩展符号从{{ 1}} [因为NodeList
是 iterable 的规范;但是请参阅this answer关于确保NodeList
是 iterable 的信息在您的环境中]。
问题2:这个逻辑是否也会遍历所有孩子?
NodeList
在文档中选择每个元素,其中许多元素也会在列表中的其他元素之内。
问题3:我们可以仅对块级元素使用此querySelector吗?
您当然可以根据当前规范对其进行定制,并且默认的querySelectorAll('*')
浏览器可以通过列出诸如display
之类的标记列表来对其应用。但这并不能告诉您什么是该页面上的块元素,因为CSS可以更改元素的querySelectorAll("div, p, h1"/*...*/)
。要获取最新信息,您需要在选择每个元素后使用getComputedStyle
并检查结果display
。
在页面上所有的元素列表可能并不理想,您可以考虑使用递归函数:
display
但这部分归结为您认为“空”的部分。 jQuery的function findEmpty(element, results = []) {
let child = element.firstChild;
if (!child) {
results.push(element);
}
while (child) {
if (child.nodeType === Node.ELEMENT_NODE) {
findEmpty(child, results);
}
child = child.nextSibling;
}
return results;
}
const allEmpty = findEmpty(document.body);
选择器是完全文字的:元素只有在没有任何子节点时才为空。但是您的定义可能更松散-例如,也许您出于您的目的考虑只包含空格(直接或在子元素中)为空的元素(在这种情况下为:empty
)。上面的第一个链接是有关MDN的DOM信息,如果需要,您可以进行很多研究以确定自己的“空”。
答案 1 :(得分:0)
您可以使用children
,它不同于childNodes
,后者可以包含任何节点,包括文本节点。如果在childNodes.length
上使用div
之类的<div>Some Text here</div>
,即使没有子元素或html标记,也会返回一个非空数组
function isEmpty(el) {
return el.children.length
}
[...document.querySelectorAll('div.parent')].filter(function(el) {
let k = isEmpty(el);
console.log(k)
});
<div class='parent'>
<div>Child 1</div>
<div>Child 1</div>
<div>Child 1</div>
<div>Child 1</div>
</div>
<div class='parent'></div>