题目
DOM 的体积过大会影响页面性能,假如你想在用户关闭页面时统计(计算并反馈给服务器)当前页面元素节点的数量总和、元素节点的最大嵌套深度以及最大子元素个数,请用 JS 配合原生 DOM API 实现需求(不用考虑陈旧浏览器以及在现代浏览器中的兼容性,可以使用任意浏览器的最新特性;不用考虑 shadow DOM)。比如在如下页面中运行后:
<html>
<head></head>
<body>
<div>
<span>f</span>
<span>o</span>
<span>o</span>
</div>
</body>
</html>
会输出:
{
totalElementsCount: 7,
maxDOMTreeDepth: 4,
maxChildrenCount: 3
}
编程实现(可以查阅相关 DOM API,但是不可以使用前端框架 or 类库):
export function calculateDOMNodes () {
// your implementation code here:
}
window.addEventListener('close', calculateDOMNodes);
回答记录
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div>
<div>
<div></div>
</div>
<div></div>
</div>
<div>
<div></div>
</div>
<script>
let counts;
window.addEventListener('beforeunload', () => {
counts = walk(document.body);
navigator.sendBeacon('http://127.0.0.1:10000/beacon', JSON.stringify(counts));
});
window.addEventListener('close', calculateDOMNodes);
function calculateDOMNodes () {
navigator.sendBeacon('http://127.0.0.1:10000/beacon', JSON.stringify(counts));
}
console.log(walk(document.body));
function walk (root) {
let start = Date.now();
let stack = [root];
let nextLevel = [];
let totalElementsCount = -1;
let maxDOMTreeDepth = 0;
let maxChildrenCount = 0;
while (stack.length || nextLevel.length) {
if (!stack.length) {
stack = nextLevel;
nextLevel = [];
maxDOMTreeDepth++;
continue;
}
let ele = stack.pop();
totalElementsCount++;
if (maxChildrenCount < ele.children.length) maxChildrenCount = ele.children.length;
nextLevel.push(...ele.children);
}
return {
totalElementsCount,
maxDOMTreeDepth,
maxChildrenCount,
time: Date.now() - start
};
}
</script>
</body>
</html>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。