【问题标题】:Determine visibility / real z-index of html elements确定 html 元素的可见性/真实 z-index
【发布时间】:2012-04-12 10:55:39
【问题描述】:

是否可以确定一个 html 元素是否对用户可见?

示例

页面有一个带有日期选择器的输入字段。如果用户单击输入字段,则会出现另一个 div,允许用户选择所需的日期。

只要日期选择器可见,它就会隐藏它后面的元素。我需要一种方法来判断一个元素是否隐藏。

第一种方法

一种方法是检查和比较z-index 值。但是如果它们被显式设置,它们总是auto

另一种方法是检查元素是否对用户可见。但我想不出任何办法。

:visible 选择器在这种情况下不起作用,因为该元素只是对用户的眼睛隐藏但仍然可见。

有什么建议吗?

【问题讨论】:

  • 我怀疑 JavaScript 是否有任何方法可以检测重叠图像是否具有透明的“颜色”。因此,即使您确实确定该对象已完全被另一张图像覆盖,您也无法知道该图像是否真的遮挡了其下方的内容。
  • 你是对的。但我可以忍受这种限制。

标签: jquery html visibility


【解决方案1】:

我尝试了一种不同的方法,使用元素坐标 (getBoundingClientRect),然后使用 elementFromPoint 查看元素是隐藏还是可见。

DEMO(按照右边的说明)

        var rectPos = this.getBoundingClientRect();

        var result = 0;
        if (this == document.elementFromPoint(rectPos.left, 
                                                    rectPos.top)) {
            result++;
        }
        if (this == document.elementFromPoint(rectPos.left, 
                                                    rectPos.bottom - 1)) {
            result++;
        }
        if (this == document.elementFromPoint(rectPos.right - 1, 
                                                     rectPos.top)) {
            result++;
        }
        if (this == document.elementFromPoint(rectPos.right - 1, rectPos.bottom - 1)) {
            result++;
        }

        if (result == 4) {
            result = 'visible';
        } else if (result == 0) {
            result = 'hidden';
        } else {
            result = 'partially visible';
        }

进一步阅读: getBoundingClientRect, elementFromPoint

【讨论】:

    【解决方案2】:

    可能有效。我没有测试过。这是我找到的一些代码的修改版本here

    function elementWithinElement(elemPossiblyCovered, elemPossiblyCovering)
    {
        var top = elemPossiblyCovered.offsetTop;
        var left = elemPossiblyCovered.offsetLeft;
        var width = elemPossiblyCovered.offsetWidth;
        var height = elemPossiblyCovered.offsetHeight;
    
        while (elemPossiblyCovered.offsetParent)
        {
            elemPossiblyCovered = elemPossiblyCovered.offsetParent;
            top += elemPossiblyCovered.offsetTop;
            left += elemPossiblyCovered.offsetLeft;
        }
    
        return (
        top >= elemPossiblyCovering.offsetTop &&
        left >= elemPossiblyCovering.offsetLeft &&
        (top + height) <= (elemPossiblyCovering.offsetTop + elemPossiblyCovering.offsetHeight) &&
        (left + width) <= (elemPossiblyCovering.offsetLeft + elemPossiblyCovering.offsetWidth)
      );
    }
    

    所以它会是这样的:

    if(elementWithinElement(myTextbox, theDatepickerDiv))
    { 
        // It's hidden
    }else
    {
        //It's visible
    }
    

    编辑:部分代码未更新。现在应该修好了。

    再次编辑:修复代码并进行测试。有效!

    【讨论】:

    • 假设我不知道这两个元素中的哪一个在前面,我该如何确定呢?
    • 如果你需要,我想你可以这样做elementWithinElement(first, second) 如果为真,“第二”在前面。那么elementWithinElement(second, first)如果为真,“first”在前面。
    • 我在这个页面上用elementWithinElement(jQuery('#chat-feature'), jQuery('#sidebar'))尝试过,但它返回false。
    • 哦,尝试抓取 javascript 对象。 elementWithinElement(jQuery('#chat-feature').get(0), jQuery('#sidebar').get(0)) 另请注意,当我意识到一些错误时,我不得不编辑该函数几次,所以请确保您拥有当前版本:)
    • 哦,当然,你是对的。谢谢,那行得通。让我在我的页面上测试一下。
    【解决方案3】:

    我能想到的唯一方法是获取每个项目的偏移量并检查新项目的偏移量不在之前任何项目的偏移量内的 onclick。很明显,仅仅靠它背后的理论来做出这样的事情需要很长时间。祝你好运:)

    【讨论】:

    • 好答案。我想这可能是唯一的方法。获取您正在检查的元素的矩形坐标,看看它是否在 datepicker div 的矩形内。要获取对象的矩形,先获取 X 和 Y 偏移量(矩形的左上点),然后获取 x + 宽度,y + 高度(矩形的右下点)
    • 是的,正是我的想法。理论上听起来很容易,但我可以想象付诸实践有点困难。虽然你可能会感到惊喜:)
    • 你描述的是碰撞检测,应该很容易实现。但是我如何确定两者中的哪一个在前面?
    • @Alp 用代码查看我的答案。你在使用 jQuery DatePicker 吗?如果是这样,日期选择器元素在隐藏时将是“显示:无”。在这种情况下,elementWithinElement 将返回 false(意味着下面的元素是可见的)
    • 我猜你必须在前面添加 z-indexing 到你想要的项目。然后检查 z-index 是否高于 0
    猜你喜欢
    • 1970-01-01
    • 2012-08-24
    • 2016-11-30
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-06
    • 1970-01-01
    相关资源
    最近更新 更多