获取div未溢出部分的高度

Posted

技术标签:

【中文标题】获取div未溢出部分的高度【英文标题】:Get height of non-overflowed portion of div 【发布时间】:2012-10-03 19:31:12 【问题描述】:

假设我有一个包装器 div,上面有一个 overflow:hidden,而内部的 div 则远远低于可见部分。如何获取内部 div 的可见高度?

<div id="wrapper" style="overflow: hidden; height:400px;">
    <div id="inner">
        <!--Lots of content in here-->
    </div>
<div>

我尝试获取内部 div 高度的每个方法都会返回包括隐藏部分在内的完整高度,即 2000 像素。我希望能够仅获取可见部分的高度,因此在本例中为 400px。

我知道我可以得到parentNode 的高度,但在生产中,内部 div 可能不是第一个孩子。所以可能有其他 div 将它们分开,因此 #inner 的高度将为 400 - 无论它与 #wrapper 之间的元素偏移量如何。

【问题讨论】:

是的...我想我可以遍历 dom 直到找到溢出隐藏标签。但其他人可能也有这个……我不知道。除非其他人提出解决方案,否则我必须绞尽脑汁。 【参考方案1】:

我认为在它旁边保留一个兄弟,计算它的 scrollTop 和溢出元素 scrollTop,然后从兄弟 scoolTop 中减去它可能会起作用

【讨论】:

这与滚动无关。【参考方案2】:

作为基本算法,这可以工作:

var offset = 0;
var node = document.getElementById("inner");
while (node.offsetParent && node.offsetParent.id != "wrapper")

    offset += node.offsetTop;
    node = node.offsetParent;

var visible = node.offsetHeight - offset;

但是,如果您正在做这些事情,也许您已经在使用 jQuery,它的 .height().offset() 函数可能会为您提供服务:

$("#wrapper").height()-
$("#inner").offset()['top']+
$("#wrapper").offset()['top'];  

【讨论】:

使用 window.getComputedStyle(node).height 是不是很糟糕 @KishoreRelangi 首先,它不适用于溢出jsfiddle.net/b5DGj/361【参考方案3】:

快速算法在 DOM 树上查找window.getComputedStyle 寻找overflow: hidden

function visibleArea(node)
    var o = height: node.offsetHeight, width: node.offsetWidth, // size
        d = y: (node.offsetTop || 0), x: (node.offsetLeft || 0), node: node.offsetParent, // position
        css, y, x;
    while( null !== (node = node.parentNode) )  // loop up through DOM
        css = window.getComputedStyle(node);
        if( css && css.overflow === 'hidden' )  // if has style && overflow
            y = node.offsetHeight - d.y;         // calculate visible y
            x = node.offsetWidth - d.x;          // and x
            if( node !== d.node )
                y = y + (node.offsetTop || 0);   // using || 0 in case it doesn't have an offsetParent
                x = x + (node.offsetLeft || 0);
            
            if( y < o.height ) 
                if( y < 0 ) o.height = 0;
                else o.height = y;
            
            if( x < o.width ) 
                if( x < 0 ) o.width = 0;
                else o.width = x;
            
            return o;                            // return (modify if you want to loop up again)
        
        if( node === d.node )                   // update offsets
            d.y = d.y + (node.offsetTop || 0);
            d.x = d.x + (node.offsetLeft || 0);
            d.node = node.offsetParent;
        
    
    return o;                                    // return if no hidden

示例fiddle(查看您的控制台)。

【讨论】:

注意,它不考虑滚动位置。【参考方案4】:

下面的代码计算元素的可见部分。可见部分是指在窗口中可见的部分,但我认为您可以轻松更改它以基于任意容器元素进行计算。

function computeVisibleHeight ($t) 
        var top = $t.position().top;
        var windowHeight = $(window).height();
        var scrollTop = $(window).scrollTop();
        var height = $t.height();

        if (top < scrollTop && height - scrollTop >= windowHeight) 
            // first case: the top and the bottom of the element is outside of the window
            return windowHeight;
         else if (top < scrollTop) 
            // second: the top is outside of the viewport but the bottom is visible
            return height - (scrollTop - top);
         else if (top > scrollTop && top + height < windowHeight) 
            // the whole element is visible
            return height;
         else 
            // the top is visible but the bottom is outside of the viewport
            return windowHeight - (top - scrollTop);
        
    

代码使用jquery。

【讨论】:

这不是问题的答案。问题不涉及视口。【参考方案5】:

我发现在任何情况下都可以这样做的唯一方法,包括当有溢出时,使用transform: translate()s,并且在元素和隐藏其溢出的元素之间还有其他嵌套容器是结合 @ 987654325@ 引用了隐藏元素溢出的祖先:

function getVisibleDimensions(node, referenceNode) 
    referenceNode = referenceNode || node.parentNode;

    var pos = node.getBoundingClientRect();
    var referencePos = referenceNode.getBoundingClientRect();

    return 
        "width": Math.min(
            node.clientWidth,
            referencePos.left + referenceNode.clientWidth - pos.left, 
            node.clientWidth - (referencePos.left - pos.left)
        ),
        "height": Math.min(
            node.clientHeight, 
            referencePos.top + referenceNode.clientHeight - pos.top,
            node.clientHeight - (referencePos.top - pos.top)
        )
    

Demo.

如果没有给出引用节点,则假定父节点:Demo。

请注意,这并没有考虑元素在视口中是否可见,只是可见(不因溢出而隐藏)。如果两者都需要,可以将功能与this answer 结合使用。它也没有检查visibility: hidden,因此如果您需要检查该节点及其所有祖先的style.visibility 属性。

【讨论】:

以上是关于获取div未溢出部分的高度的主要内容,如果未能解决你的问题,请参考以下文章

CSS - 高度坍塌和外边距溢出问题及解决方法

如何在 Tailwindcss 中修复 div 高度溢出父 div

父级中的div高度溢出[重复]

如何使用 jQuery 获取 div 全部内容的高度?

使用溢出时没有滚动条:自动和 div 高度

高度为 100% 的 Div 溢出到其父级下方的 flexbox 行 [重复]