当css高度设置为0时,用js找出elemet的真实高度

问题描述 投票:0回答:3

我正在尝试创建一个打开和关闭菜单的脚本。问题是我需要计算出元素的高度,而它的高度从 css 设置为 0。

我想出了一个非常丑陋的解决方案,我想知道是否有更优雅的方法来做到这一点。

我的解决方案是将可见性设置为隐藏,然后将高度设置为自动,然后查询高度,然后设置回高度和可见性。

我需要这个用于 css 动画,因为 css anim 它不适用于高度自动和高度 0px,我需要以 px 为单位的高度。

这是我的代码:

document.getElementById('menu_button').onclick = function() {
        if (document.getElementById('mobile-menu').style.height == '0px') {
            document.getElementById('mobile-menu').style.visibility = 'hidden';
            document.getElementById('mobile-menu').style.height = 'auto';
            var MobileMenuHeight = document.getElementById('mobile-menu').clientHeight;
            document.getElementById('mobile-menu').style.height = '0px';
            document.getElementById('mobile-menu').style.visibility = 'visible';
            setTimeout(() => { document.getElementById('mobile-menu').style.height = MobileMenuHeight + 'px'; }, 50);
        } else {
            document.getElementById('mobile-menu').style.height = "0px";
        }
    }
javascript
3个回答
0
投票

您可以使用

getComputedStyle

if (getComputedStyle(document.getElementById('mobile-menu')).height == '0px')

0
投票

最后我想出了一个更好且简单的解决方案。

我只是将菜单放入带有

overflow: hidden
的容器中,然后缩放容器,这样菜单本身就可以保持其高度。

function toggleMobileMenu() {
    document.getElementById('menu-button').onclick = function() {
        var MobileMenuHeight = document.getElementById('mobile-menu').clientHeight;
        var MenuContainerHeight = document.getElementById('mobile-menu-container').clientHeight;
        if (MenuContainerHeight == 0) {
            document.getElementById('mobile-menu-container').style.height = MobileMenuHeight + 'px';
        } else {
            document.getElementById('mobile-menu-container').style.height = "0px";
        }
    }
}

document.onload = toggleMobileMenu();
#menu-button {
    position: absolute;
    width: 40px;
    height: 40px;
    right: 16px;
    top: 60px;
    z-index: 98;
    }
#menu-button div {
    width: 90%;
    height: 6px;
    margin: 6px auto;
    background-color: #555;
    border-radius: 3px;
}
.mobile-menu-container {
    background: #ddd;
    overflow: hidden;
    height: 0;
    transition: height 0.33s;
}
.mobile-menu {
    background: #8888ff;
}
<html>
<head>
<meta charset = "UTF-8">
</head>
<body>

<div id="menu-button"><div></div><div></div><div></div></div>

<div id = "mobile-menu-container" class = "mobile-menu-container">
    <div class = "mobile-menu" id="mobile-menu">        
        <div class="menu-container">
            <ul>
                <li><a href="#">Menu item 1</a></li>
                <li><a href="#">Menu item 1</a></li>
                <li><a href="#">Menu item 1</a></li>
                <li><a href="#">Menu item 1</a></li>
                <li><a href="#">Menu item 1</a></li>
            </ul>
        </div>      
    </div>
</div>

</body>


0
投票

有点晚了,但有些人可能会发现它有用......

我使用与您的第一个版本类似的方法。我用它来实现“折叠”和“展开”之间的平滑高度过渡。可折叠元素以 style.height === "0px" 开头。然后第一步是将元素 style.height 设置为“auto”并读出计算出的高度:

collapsibleElement.style.height = "auto" ;
const targetHeight = window.getComputedStyle( collapsibleElement ).height ;

然后立即切换回零高度。此外,溢出属性也发生了变化,这对于避免水平滚动条引起的复杂情况至关重要。

collapsibleElement.style.height = "0px" ;
collapsibleElement.style.overflow = "visible clip" ;

那么技巧就是在高度变化开始之前使用两个(!)连续延迟:

window.requestAnimationFrame(() => 
window.requestAnimationFrame(() => {
    controller.setAttribute( "data-collapsible-state", "expanded" );
    collapsibleElement.style.height = targetHeight;
    } ) ) ;

单个 requestAnimationFrame() 有时不足以在转换开始之前解决文档状态。同样,setTimeout()有时会失败,甚至双重和三重嵌套调用偶尔也会失败,导致transitionend事件无法调度。

转换结束事件处理程序完成转换:

if ( evt.target.style.height !== "0px" ) {
    evt.target.style.height = "auto" ;
    evt.target.style.overflow = "visible visible";
} else {
    evt.target.style.overflow = "clip clip" ;
    }
evt.stopPropagation( );
© www.soinside.com 2019 - 2024. All rights reserved.