是否有方法计算所有DOM元素的堆叠上下文,以便使用JavaScript比较上述位置的任意两个元素?

是否有方法计算所有DOM元素的堆叠上下文,以便使用JavaScript比较上述位置的任意两个元素?,javascript,css,dom,Javascript,Css,Dom,我试图比较DOM中的任意两个元素,看看它们是否要绘制(在屏幕上渲染)在同一个区域(坐标重叠),其中一个在另一个之上。这个问题不是关于重叠计算,而是关于比较DOM树任何部分的任意两个元素的上述位置(计算堆栈上下文、z索引和HTML层次结构…) 虽然我对这个领域还不熟悉,但我的方法将遍历每个HTML元素并为其分配一个数值,同时考虑规则和标准。另一个问题是正确地获取它们。我找不到一个已经这样做的JS库 有关css和完整代码示例,请参阅。。。 预期的输出是比较任意两个HTML元素的上下位置(3D)的能

我试图比较DOM中的任意两个元素,看看它们是否要绘制(在屏幕上渲染)在同一个区域(坐标重叠),其中一个在另一个之上。这个问题不是关于重叠计算,而是关于比较DOM树任何部分的任意两个元素的上述位置(计算堆栈上下文、z索引和HTML层次结构…)

虽然我对这个领域还不熟悉,但我的方法将遍历每个HTML元素并为其分配一个数值,同时考虑规则和标准。另一个问题是正确地获取它们。我找不到一个已经这样做的JS库

有关css和完整代码示例,请参阅。。。

预期的输出是比较任意两个HTML元素的上下位置(3D)的能力。如果我从这里的专业人士那里得到一个想法并能够实现它,我将分享我的代码。非常感谢您的帮助。

npm上有一个名为
堆叠顺序的
,它正是这样做的

您可以通过以下方式安装它:

$npm安装堆叠订单
从“堆叠订单”导入堆叠订单;
或者在脚本标记中使用


然后,只要调用
stackingOrder.compare(element1,element2)

const element1=document.querySelector(“#element1”);
const element2=document.querySelector('#element2');
const order=stackingOrder.compare(元素1,元素2);
如果(顺序==1)
log('element1在element2`之上)
其他的
log('element2'下的element1')
最简单的方法是使用它,它将在给定的点上按堆叠顺序提供所有元素

复杂的部分是,您需要找到两个元素相交的点

下面的示例将搜索左上角的最共享点,并演示您必须更精确地定义约束,因为它会故意遗漏仍在元素之间的元素:

测试('red','blue');//-2(蓝色:2,红色:4)
测试(‘红色’、‘绿色’);//-2(绿色:1,红色:4),但在选定点蓝色不可见
测试(‘黄色’、‘绿色’);//-1(黄色:3,绿色:1),但在选定点蓝色不可见
测试(‘蓝色’、‘绿色’);//-1(蓝色:2,绿色:1)
功能测试(1类、2类){
常量elem1=document.querySelector('.'+class1);
常量elem2=document.querySelector('.'+class2);
log(class1,class2,getStackDistance(elem1,elem2));
}
函数getStackDistance(elem1,elem2){
const shared_point=findSharedPoint(elem1,elem2);
如果(!共享_点){
console.error('no shared point');
返回NaN;
}
常量完整列表=document.elementsFromPoint(shared_point.x,shared_point.y);
返回full_list.indexOf(elem1)-full_list.indexOf(elem2);
}
//返回两个元素之间最左上角的共享点
函数findSharedPoint(elem1,elem2){
常量bbox1=elem1.getBoundingClientRect(elem1);
常量bbox2=elem2.getBoundingClientRect(elem2);
常数相交盒={
左:Math.max(bbox1.left,bbox2.left),
右:Math.min(bbox1.right,bbox2.right),
top:Math.max(bbox1.top,bbox2.top),
底部:Math.min(bbox1.bottom,bbox2.bottom)
};
如果(左相交>右相交)||
相交(长方体顶部>相交(长方体底部){
返回null;
}
返回{x:intersect\u box.left,y:intersect\u box.top};
}
.box{
宽度:50px;
高度:50px;
位置:绝对位置;
不透明度:0.7;
}
瑞德先生{
背景:红色;
顶部:20px;
左:20px;
z指数:4;
}
蓝先生{
背景:蓝色;
顶部:40px;
左:40px;
z指数:2;
}
黄先生{
背景:黄色;
顶部:10px;
左:20px;
z指数:3;
}
格林先生{
背景:绿色;
顶部:40px;
左:10px;
z指数:1;
}