【发布时间】:2013-12-31 22:37:56
【问题描述】:
给定一个网页,如何找到网页上最大的矩形,它是主要内容区域?
例如,比较侧边栏、页眉、页脚和主要内容区域的大小。是否可以通过在页面上发现的所有矩形中搜索最大的矩形来找到主要内容区域?
通常怀疑最高和最宽的矩形是主要内容区域,想知道是否有某种 JavaScript 或 Python 算法来检验这个假设。
【问题讨论】:
标签: javascript python dom rectangles
给定一个网页,如何找到网页上最大的矩形,它是主要内容区域?
例如,比较侧边栏、页眉、页脚和主要内容区域的大小。是否可以通过在页面上发现的所有矩形中搜索最大的矩形来找到主要内容区域?
通常怀疑最高和最宽的矩形是主要内容区域,想知道是否有某种 JavaScript 或 Python 算法来检验这个假设。
【问题讨论】:
标签: javascript python dom rectangles
因此,虽然这个问题对我来说没有多大意义,但我还是忍不住想玩弄递归扫描 DOM 树以按元素大小检索和排序元素的概念:)
这是一个愚蠢的功能(您可以将其粘贴到浏览器控制台中):
function scanSizes(root) {
return [].reduce.call(root, function(sizes, node) {
var bounds = node.getBoundingClientRect();
sizes.push({tag: node.outerHTML, area: bounds.width * bounds.height});
var children = node.querySelectorAll("*");
if (children.length > 0)
sizes.push.apply(sizes, scanSizes(children));
return sizes;
}, []).sort(function(x, y) {
var a = x.area, b= y.area;
return a > b ? -1 : a < b ? 1 : 0;
});
}
var sizes = scanSizes(document.querySelectorAll("body > *"));
// sizes[0].tag contains the largest html tag (as a string)
// sizes[0].area its area size in pixels (width * height)
编辑:更严肃地说,您可能对this topic 和相关答案感兴趣。
编辑:当然,基于性能的递归并不是一个好主意。您可以使用这样的方法来获得更有效的解决方案:
function scanSizes(root) {
return [].map.call(root, function(node) {
var bounds = node.getBoundingClientRect();
return {tag: node.outerHTML, area: bounds.width * bounds.height};
}).sort(function(x, y) {
var a = x.area, b= y.area;
return a > b ? -1 : a < b ? 1 : 0;
});
}
var sizes = scanSizes(document.querySelectorAll("*"));
【讨论】:
RangeError: Maximum call stack size exceeded
我正在添加另一个答案,因为我刚刚偶然发现了 <main> HTML5 element spec,开发人员应该使用它来定义他们的主要内容区域,所以这可能是您想要检查的第一个元素抓取页面。
所以基本上你应该检查页面中的任何单个<main> 或role="main" 元素,然后只使用其他内容检测策略:)
【讨论】:
当前的答案过于复杂。您需要了解的主要内容是element.getBoundingClientRect();。这是一个较小的函数 - 我正在寻找最大的 table 但你可以使用任何你想要的 CSS 选择器。
// Fix NodeList.sort()
NodeList.prototype.sort = Array.prototype.sort
var elements = document.querySelectorAll('table')
var getArea = function(element){
var rectangle = element.getBoundingClientRect();
return rectangle.width * rectangle.height;
}
elements.sort(getArea)[0]
【讨论】: