我正在尝试比较DOM中的任何两个元素,以查看它们是否要在同一区域(坐标重叠)上绘制(渲染在屏幕上),而一个区域要高于另一个区域。这个问题不是关于重叠计算,而是关于比较DOM树任何部分中的任意两个元素以获得上述位置(计算堆栈上下文以及z-index和HTML层次结构...)。
尽管我是这个领域的新手,但是我的方法还是会遍历并考虑规则和标准,为每个HTML元素分配一个数值。另一个问题是正确地获取它们。我找不到已经做到这一点的JS库。
有关CSS和完整代码示例,请参见... https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
预期的输出是比较上方或下方位置(3D)的任何两个HTML元素的能力。如果我从这里的专业人员那里得到一个想法并能够实现它,我将分享我的代码。谢谢您的帮助。
答案 0 :(得分:1)
npm上有一个名为fun beSave() {
try {
// some blackbox code
}
catch (e: Exception) {
// handler
}
}
的{{3}},就是这样做的。
您可以通过以下方式安装它:
stacking-order
$ npm install stacking-order
或在脚本标签中使用package。
import stackingOrder from 'stacking-order';
然后找到您要查找的内容,只需致电<script src="https://npmcdn.com/stacking-order"></script>
stackingOrder.compare(element1, element2)
答案 1 :(得分:1)
最简单的方法是使用document.elementsFromPoint()
,它将在给定的位置按堆叠顺序为您提供所有元素。
复杂的部分是您需要找到两个元素都将相交的点。
下面的示例将搜索最左上角的共享点,并说明您必须更精确地定义约束,因为它会故意遗漏仍位于元素之间的元素:
test( 'red', 'blue' ); // -2 (blue:2, red:4)
test( 'red', 'green' ); // -2 (green:1, red:4) but at selected point blue is not visible
test( 'yellow', 'green' ); // -1 (yelow:3, green:1) but at selected point blue is not visible
test( 'blue', 'green' ); // -1 (blue:2, green: 1)
function test( class1, class2 ) {
const elem1 = document.querySelector( '.' + class1 );
const elem2 = document.querySelector( '.' + class2 );
console.log( class1, class2, getStackDistance( elem1, elem2 ) );
}
function getStackDistance( elem1, elem2 ) {
const shared_point = findSharedPoint( elem1, elem2 );
if( !shared_point ) {
console.error( 'no shared point' );
return NaN;
}
const full_list = document.elementsFromPoint( shared_point.x, shared_point.y );
return full_list.indexOf( elem1 ) - full_list.indexOf( elem2 );
}
// returns top-left-most shared point between two elements
function findSharedPoint( elem1, elem2 ) {
const bbox1 = elem1.getBoundingClientRect( elem1 );
const bbox2 = elem2.getBoundingClientRect( elem2 );
const intersect_box = {
left: Math.max( bbox1.left, bbox2.left ),
right: Math.min( bbox1.right, bbox2.right ),
top: Math.max( bbox1.top, bbox2.top ),
bottom: Math.min( bbox1.bottom, bbox2.bottom )
};
if( intersect_box.left > intersect_box.right ||
intersect_box.top > intersect_box.bottom ) {
return null;
}
return { x: intersect_box.left, y: intersect_box.top };
}
.box {
width: 50px;
height: 50px;
position: absolute;
opacity: 0.7;
}
.red {
background: red;
top: 20px;
left: 20px;
z-index: 4;
}
.blue {
background: blue;
top: 40px;
left: 40px;
z-index: 2;
}
.yellow {
background: yellow;
top: 10px;
left: 20px;
z-index: 3;
}
.green {
background: green;
top: 40px;
left: 10px;
z-index: 1;
}
<div class="box red"></div>
<div class="box blue"></div>
<div class="box yellow"></div>
<div class="box green"></div>