如何获取导航栏动态高度,实现aside元素自动适配导航定位切换
动态适配导航栏fixed定位时的aside元素位置
问题说明
导航栏默认位于页面顶部,当页面滚动距离超过20px时添加fixed类变为固定定位,此时aside元素会上移至页面顶部,覆盖部分导航栏。目前通过手动设置margin-top调整位置,希望改为根据导航栏实际高度自动适配,无需手动指定数值。
解决方案
核心思路
通过JavaScript获取导航栏的实际渲染高度,在导航栏切换为fixed定位时,将该高度赋值给aside元素的margin-top属性;同时监听窗口大小变化,确保导航栏高度改变时能实时更新适配值。
具体实现步骤
- 获取导航栏高度:使用
offsetHeight属性获取导航栏的实际高度(包含padding、border等,是元素在页面中占据的真实高度)。 - 滚动事件中动态赋值:在滚动判断逻辑里,替换手动设置的固定数值为动态获取的高度值。
- 监听窗口resize事件:当窗口大小改变导致导航栏高度变化时,重新计算并更新aside的margin-top。
修改后的代码
HTML部分(无需改动)
<nav> <i class="uil uil-list-ul" id="inMenu"></i> <img src="../../imgs/BCG-logos_white.png" alt=""> <form id="search" action=""> <input type="text" placeholder="Your Books"> <button><i class="uil uil-search"></i></button> </form> <div id="Login"> <i class="uil uil-draggabledots"></i> <button><i class="uil uil-user"></i> Đăng Nhập</button> </div> </nav> <aside style="width: 0px;"> <i class="uil uil-times-square" id="outMenu"></i> <div class="menu-header" id="BookTag"> <h4><i class="uil uil-label-alt"></i> Book Tag</h4> <ul> <li><a href=""><i class="uil uil-book "></i> Sách Việt Nam</a></li> <li><a href=""><i class="uil uil-book "></i> Sách Ngoại Quốc</a></li> </ul> </div> <div class="menu-header" id="ComicTag"> <h4><i class="uil uil-label-alt"></i> Comic Tag</h4> <ul> <li><a href=""><i class="uil uil-swatchbook"></i> Truyện Việt Nam</a></li> <li><a href=""><i class="uil uil-swatchbook"></i> Truyện Ngoại Quốc</a></li> </ul> </div> <div class="menu-header" id="GameTag"> <h4><i class="uil uil-label-alt"></i> Game Tag</h4> <ul> <li><a href=""><i class="uil uil-headphones-alt "></i> Game Việt Nam</a></li> <li><a href=""><i class="uil uil-headphones-alt "></i> Game Ngoại Quốc</a></li> </ul> </div> <div class="menu-header" id="Author"> <h4><i class="uil uil-edit-alt"></i> Author</h4> <ul> <li><a href=""><i class="uil uil-book-open"></i> Review DashBoard</a></li> <li><a href=""><i class="uil uil-books"></i> Review Request</a></li> <li><a href=""><i class="uil uil-book-reader"></i> Top Author</a></li> </ul> </div> <div class="menu-header" id="forum"> <h4><i class="uil uil-podium"></i> Forum</h4> <ul> <li><a href=""><i class="uil uil-download-alt"></i> Download Book</a></li> <li><a href=""><i class="uil uil-post-stamp"></i> Book Request</a></li> <li><a href=""><i class="uil uil-arrow-growth"></i> Nomination Book</a></li> <li><a href=""><i class="uil uil-download-alt"></i> Download Comic</a></li> <li><a href=""><i class="uil uil-post-stamp"></i> Comic Request</a></li> <li><a href=""><i class="uil uil-arrow-growth"></i> Nomination Comic</a></li> <li><a href=""><i class="uil uil-download-alt"></i> Download Game</a></li> <li><a href=""><i class="uil uil-post-stamp"></i> Game Request</a></li> <li><a href=""><i class="uil uil-arrow-growth"></i> Nomination Game</a></li> <li><a href=""><i class="uil uil-envelope"></i> Create discuss</a></li> </ul> </div> <div class="menu-header" id="About"> <h4><i class="uil uil-channel"></i> About Us</h4> </div> <div class="menu-header" id="Contact"> <h4><i class="uil uil-comment-alt-medical"></i> Contact Us</h4> </div> <div class="menu-header" id="FAQ"> <h4><i class="uil uil-question-circle"></i> FAQ</h4> </div> </aside>
CSS部分(补充优化)
/* Navigation */ nav { background-color: #172B4D; display: flex; padding: 5px 30px; position: relative; align-items: center; justify-content: space-between; z-index: 100; width: 100%; box-sizing: border-box; /* 确保padding不会撑开宽度 */ } .fixed { position: fixed; top: 0; left: 0; /* 固定后靠左对齐,避免宽度收缩 */ } /* Navigation hidden menu */ nav>i { font-size: 15px; color: #F0F0F0; position: absolute; top: 40px; left: 15px; transition: transform 1s, background-color 1s; background-color: #172B4D; width: 30px; height: 30px; display: flex; align-items: center; justify-content: center; border-radius: 50%; cursor: pointer; } nav>i:hover { background-color: #000000; transform: rotate(0.5turn); } /* End Navigation Hidden Menu */ /* Navigation Logo Image */ nav>img { width: 7%; } /* End of Logo Navigation */ /* Search Navigation */ nav>form { width: 40%; display: flex; } nav>form>input { width: 90%; height: 25px; border: none; outline: none; padding: 0 10px; border-radius: 45px 0 0 45px; } nav>form>button { width: 10%; border: none; border-radius: 0 45px 45px 0; cursor: pointer; } /* End Search Navigation */ /* Setting and Login Navigation */ nav>#Login { width: 115px; display: flex; justify-content: space-between; align-items: center; } nav>#Login>i { color: #F0F0F0; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center; border-radius: 50%; cursor: pointer; transition: background-color 0.75s, transform 0.75s; } nav>#Login>i:hover { background-color: #000000; transform: rotate(0.25turn); } nav>#Login>button { background-color: transparent; border: none; color: #F0F0F0; border-radius: 45px; padding: 2px 4px; cursor: pointer; transition: background-color 0.5s; } nav>#Login>button:hover { background-color: #000000; } /* End Setting and Log Navigation */ /* End Navigation */ /* Article */ article { height: 5000px; } /* Aside */ aside { background-color: #172B4D; color: #F0F0F0; padding-top: 30px; position: fixed; overflow: auto; transition: width 0.75s; height: 100%; z-index: 100; } /* Hide aside button */ aside>i { position: absolute; top: 10px; right: 10px; transition: color .5s; } aside>i:hover { color: #5895ff; } /* End hidden aside button */ /* Menu heading */ aside>.menu-header { cursor: pointer; } aside>.menu-header>h4:hover { color: #86785d; background-color: #021537; cursor: pointer; } aside>.menu-header>h4 { padding: 5px 10px; background-color: #00225d; border: 1px solid #172B4D; font-size: 0px; transition: font-size 0.75s; color: #B3BAC5; } /* End menu item */ /* Sub menu item */ aside>.menu-header>ul { padding-left: 30px; list-style: none; height: 0; overflow: hidden; } aside>.menu-header>.show { height: unset; } .menu-header>ul>li>a { color: #E3EDFF; font-size: 13px; padding: 5px; text-decoration: none; } .menu-header>ul>li>a:hover { color: #86785d; } /* End menu sub-item */ /* End Aside */
JavaScript部分(核心修改)
const nav = document.querySelector('nav'); const aside = document.querySelector('aside'); const section1 = document.querySelector('#s-1'); // 封装布局更新逻辑,避免重复代码 function updateLayout() { const navHeight = nav.offsetHeight; if (window.scrollY >= 20) { nav.classList.add("fixed"); section1.style.paddingTop = `${navHeight + 80}px`; // 导航栏高度+固定偏移量,替代原手动130px aside.style.marginTop = `${navHeight}px`; } else { nav.classList.remove("fixed"); section1.style.paddingTop = "50px"; aside.style.marginTop = "unset"; } } // 页面加载时先执行一次,确保初始状态正确 updateLayout(); // 监听滚动事件 window.addEventListener('scroll', updateLayout); // 监听窗口大小变化,实时更新适配值 window.addEventListener('resize', updateLayout);
关键说明
offsetHeight返回元素的像素高度,包含元素自身高度、内边距和边框,能准确获取导航栏的实际占位高度。- 新增
box-sizing: border-box和left:0是为了避免导航栏fixed后出现宽度收缩、位置偏移的问题。 - 将逻辑封装到
updateLayout函数中,既减少冗余代码,也方便在滚动和窗口 resize 事件中复用。
内容的提问来源于stack exchange,提问作者Noob tv
相关产品推荐
相关产品推荐

