Javascript扫描线算法查找具有相同x坐标的所有元素

时间:2012-08-27 17:16:39

标签: javascript algorithm

我正在尝试使用 PURE Javascript(没有其他框架)实现线扫描算法,它基本上从左到右扫描屏幕并查看共享的所有元素(包括重叠元素)相同的x坐标。

例如

I have 6 div with border layout randomly on the screen, and I am using a vertical line (blue dotted line) to scan through it from left to right.

我有6个带有黑色边框的div元素,它们都在屏幕上随机排列。为了便于说明,我使用垂直虚线蓝线从左到右扫过飞机。目标是报告该行传递的所有元素。对于上面的示例,我们如何使用JavaScript报告Div ADiv EDiv D以及hyperlink D中的Div D

2 个答案:

答案 0 :(得分:3)

您可以使用getBoundingClientRect method获取元素的位置。然后循环遍历它们并检查它们是否与您的扫描匹配:

var all = document.body.getElementsByTagName("*");
var x = /* blue line */;
var match = [];
for (var i=0; i<all.length; i++) {
    var rect = all[i].getBoundingClientRect();
    if (rect.left < x && rect.right > x)
        match.push(all[i]);
});

更短,更实用的方式:

var match = Array.prototype.filter.call(document.body.querySelectorAll("*"), function(el) {
    var rect = el.getBoundingClientRect();
    return rect.left < x && rect.right > x;
});

如果您需要经常使用的快速访问功能,您可以将所有元素(及其坐标)存储在已排序的数据结构segment tree中,您可以在其中搜索它们。

此外,当确保DOM元素的子节点不超过其父节点边界时,您可以轻松地将DOM本身用作搜索树:

var x = /* the blue line */;
var match = function find(el, set) {
    var rect = el.getBoundingClientRect();
    if (rect.left < x && rect.right > x) {
        set.push(el);
        for (var i=0; i<el.children.length; i++)
            find(el.children[i]);
    }
    return set;
}(document.body, []);

答案 1 :(得分:1)

  1. 收集所有DOM元素
  2. Find their positions并将它们存储在数组中(这样您就可以再次使用数据而无需通过DOM)
  3. 遍历数组并求解x