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

Javascript扫描线算法查找具有相同x坐标的所有元素,javascript,algorithm,Javascript,Algorithm,我试图通过使用PUREJavascript(没有其他框架)实现行扫描算法,它基本上从左到右扫描屏幕,并查看共享相同x坐标的所有元素(包括重叠元素) 比如说 我有6个带有黑色边框的div元素,它们都在屏幕上随机布局。为了便于说明,我使用一条垂直的蓝色虚线从左到右扫描整个平面。目标是报告行经过的所有元素。对于上面的示例,我们如何使用JavaScript报告diva、dive、divd以及divd中的hyperlink D 收集所有DOM元素 并将它们存储在一个数组中(这样您就可以在不通过DOM的情

我试图通过使用PUREJavascript(没有其他框架)实现行扫描算法,它基本上从左到右扫描屏幕,并查看共享相同x坐标的所有元素(包括重叠元素)

比如说

我有6个带有黑色边框的
div
元素,它们都在屏幕上随机布局。为了便于说明,我使用一条垂直的蓝色虚线从左到右扫描整个平面。目标是报告行经过的所有元素。对于上面的示例,我们如何使用JavaScript报告
diva
dive
divd
以及
divd
中的
hyperlink D

  • 收集所有DOM元素
  • 并将它们存储在一个数组中(这样您就可以在不通过DOM的情况下再次使用数据)
  • 循环遍历数组并求解x

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

    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 all=document.body.getElementsByTagName(“*”);
    var x=/*蓝线*/;
    var匹配=[];
    对于(var i=0;i),您可以在其中搜索它们

    此外,当保证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, []);
    
    var x=/*蓝线*/;
    变量匹配=函数查找(el,集合){
    var rect=el.getBoundingClientRect();
    if(rect.leftx){
    设置。推(el);
    
    对于(var i=0;我需要注意:
    getElementsByTagName(“*”)
    queryselectoral(“*”)
    (另外,您可以使用
    document.all
    ,如果存在的话)。我不会使用
    过滤器,而只是对
    使用一个简单的
    。但这一切都取决于任务是否对性能至关重要。querySelector似乎在Opera中得到了增强:-)当然,一个循环可以做到这一点,但我喜欢函数式编程……我想知道它是否总是要检索所有的元素,然后逐个进行迭代?因为你知道迭代可能需要数千个DOM元素,我的意思是。有没有一种方法可以让我们按照坐标排序,然后再进行一次迭代像这样的二进制搜索?@Bergi哇,Opera在
    querySelectorAll
    上的表现确实令人印象深刻。显然,他们做了一些完全不同的事情——而且效率也非常高。我没有意识到这一点。如果他们能对
    getElementsByTagName
    做同样的事情……顺便说一句,我也喜欢函数式编程,但是t、 …我很少使用它,因为它与经典迭代相比太慢了:(@user1389813)你为什么要对元素进行排序,真的吗?它们可以是10行、1000行或100万行,但你仍然有一个5行循环。排序的问题是它的速度慢得多,因为它必须遍历所有元素,在大多数情况下不止一个元素,并且每次都进行比较。你会如何对它们进行排序?按左键排序纵坐标?或右坐标?或中点?然后,您将如何使用二进制搜索?那么,您为什么不应用测试用例并通过单个循环获得您想要的所有元素?
    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, []);