W3C CSS Specification描述了兼容渲染引擎应该实现的堆叠上下文.但是,我找不到一种在JavaScript程序,跨浏览器中访问此信息的方法.所有我可以读取的是css z-index属性,这本身并不多说,因为大多数时间被设置为自动,或者甚至当表示为数值时,不是实际显示的可靠指标(如果它们属于不同的统计上下文,则比较z-索引是无关紧要的).
请注意,我对任意元素感兴趣:如果这两个元素都在鼠标指针下面,那么只有一个被认为是“悬停”,所以我可以在这种情况下找到最接近的元素.但是,我正在寻找一个更通用的解决方案,最好是不需要重新实现渲染引擎已经执行的堆叠算法.
更新:让我澄清一下这个问题背后的原因:我最近解决了a question,暴露了jQuery的拖放机制的限制 – 在丢弃时不考虑z指标,所以如果一个元素掩盖了另一个元素,那么仍然可以在“后面”的元素中执行放置操作.虽然在OP特定案件中回答了相关问题,但一般问题仍然存在,我不知道的简单解决方案.
下面的alex’s answer是有用的,但对于现在的情况是不够的:拖动时,拖动的元素本身(或更准确地说,它的帮助器)是鼠标光标下的最顶层元素,因此elementFromPoint将返回它而不是下一个最高元素,我们真的需要(解决方法:style the cursor,所以它被放置在助手之外). jQuery使用的其他交叉策略也考虑到不止一个点,使确定与帮助器相交的最顶层元素的任务复杂化.能够通过实际的z-index比较(或排序)元素将使一般情况下“z-index感知”交叉模式成为可行.
解决方法
front = $.fn.visuallyInFront(document.documentElement,document.body); // front == <body>...</body> because the BODY node is 'on top' of the HTML node
推理
还有其他方法可以确定哪个元素位于另一个之上.例如document.elementFromPoint()或document.elementsFromPoint()弹出来.然而,有许多(无证件)因素影响这些方法的可靠性.例如,不透明度,可见性,指针事件,背景可见性和某些转换可能会使document.elementFromPoint()无法对特定元素进行测试.那么document.elementFromPoint()只能查询最顶层的元素(而不是底层的元素).这应该用document.elementsFromPoint()解决,但目前只在Chrome中实现.除此之外,我向Chrome开发人员提供了关于document.elementsFromPoint()的错误.当测试锚标签时,所有底层元素都不被忽视.
所有这些问题结合起来,我决定尝试重新实施堆垛机制.这种方法的好处是堆叠机制被广泛记录,并且可以被测试和理解.
怎么运行的
我的方法重新实现了HTML堆叠机制.它的目标是正确遵循影响HTML元素堆叠顺序的所有规则.这包括定位规则,浮动,DOM顺序,也包括CSS3属性,如不透明度,变换和更多实验属性,如过滤器和掩码.规则似乎在2016年3月正式实施,但在规范和浏览器支持更改时,将来需要更新.
我将所有内容都整理在GitHub repository中.希望这种方法能够可靠地运行.这是一个example JSFiddle的代码在行动.在示例中,所有元素都按照实际的“z-index”进行排序,这是OP之后.
对这种方法的测试和反馈将是非常欢迎!