JavaScript实现元素吸顶的方法详解
背景
页面内的tab导航需要在滚动到视口顶部的时候进行吸顶,这个功能算是比较常见,也比较容易实现。刚开始按照自己想到的最简单的方法来实现,写完代码后进行测试,发现页面有很明显的bug,心里直呼大意了,特此记录下。
错误示例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <style> .page-container { width: 1200px; margin: 0 auto; } .top-area { height: 300px; background-color: lightskyblue; margin-bottom: 20px; } .tab { padding: 0 20px; display: flex; justify-content: space-between; background-color: #f4f4f4; } .tab.fixed { position: fixed; width: 1200px; box-sizing: border-box; top: 0; } .tab > div { padding: 10px 20px; } .waterfall { display: flex; justify-content: space-between; flex-wrap: wrap; align-content: center; } .waterfall > div { margin-top: 20px; width: 220px; height: 300px; background-color: darkseagreen; margin-bottom: 12px; } </style> </head> <body> <div class="page-container"> <div class="top-area">huge element</div> <div class="tab"> <div class="tab1">tab1</div> <div class="tab2">tab2</div> <div class="tab3">tab3</div> <div class="tab4">tab4</div> <div class="tab5">tab5</div> <div class="tab6">tab6</div> <div class="tab7">tab7</div> <div class="tab8">tab8</div> <div class="tab9">tab9</div> <div class="tab10">tab10</div> </div> <div class="tab-holder"></div> <div class="waterfall"> <div class="item1">item1</div> <div class="item2">item2</div> <div class="item3">item3</div> <div class="item4">item4</div> <div class="item5">item5</div> <div class="item6">item6</div> <div class="item7">item7</div> <div class="item8">item8</div> <div class="item9">item9</div> <div class="item10">item10</div> <div class="item11">item11</div> <div class="item12">item12</div> <div class="item13">item13</div> <div class="item14">item14</div> <div class="item15">item15</div> <div class="item16">item16</div> <div class="item17">item17</div> <div class="item18">item18</div> <div class="item19">item19</div> <div class="item20">item20</div> <div class="item21">item21</div> <div class="item22">item22</div> <div class="item23">item23</div> <div class="item24">item24</div> <div class="item25">item25</div> <div class="item26">item26</div> <div class="item27">item27</div> <div class="item28">item28</div> <div class="item29">item29</div> <div class="item30">item30</div> <div class="item31">item31</div> <div class="item32">item32</div> <div class="item33">item33</div> <div class="item34">item34</div> <div class="item35">item35</div> <div class="item36">item36</div> <div class="item37">item37</div> <div class="item38">item38</div> <div class="item39">item39</div> <div class="item40">item40</div> <div class="item41">item41</div> <div class="item42">item42</div> <div class="item43">item43</div> <div class="item44">item44</div> <div class="item45">item45</div> <div class="item46">item46</div> <div class="item47">item47</div> <div class="item48">item48</div> <div class="item49">item49</div> <div class="item50">item50</div> </div> </div> </body> <script> const tabElem = document.querySelector(".tab"); const tabHolder = document.querySelector(".tab-holder"); const handleScroll = () => { const { top, height } = tabElem.getBoundingClientRect(); console.log("top", top); if (top < 0) { tabElem.classList.add("fixed"); tabHolder.style.height = height + "px"; } else { tabElem.classList.remove("fixed"); tabHolder.style.height = 0; } }; document.addEventListener("scroll", handleScroll); </script> </html>
上面的代码在打开页面后,向上滚动过程中会发现tab导航一直在闪烁,原因就是tab元素在转变成固定定位的过程,浏览器需要重新计算页面布局和重绘元素,在此期间滚动事件执行了很多遍,导致获取到的top值会出现两极跳转现象,元素会固定定位和原来的定位之间来回切换。
解决方案
上面的代码由于tab导航元素的定位会发生变化,导致在滚动过程中获取到的top值有问题,之前我们是使用需要定位的上边界来进行判断,那么我们可以选取相邻元素的上下边界是否达到条件来作为tab导航是否应该转为固定定位的依据。
const topAreaElem = document.querySelector(".top-area"); const tabElem = document.querySelector(".tab"); const tabHolder = document.querySelector(".tab-holder"); const handleScroll = () => { const { bottom } = topAreaElem.getBoundingClientRect(); const { height } = tabElem.getBoundingClientRect(); // 这个20是tab导航与上面相邻元素之间的margin if (bottom + 20 < 0) { tabElem.classList.add("fixed"); tabHolder.style.height = height + "px"; } else { tabElem.classList.remove("fixed"); tabHolder.style.height = 0; } }; document.addEventListener("scroll", handleScroll);
到此这篇关于JavaScript实现元素吸顶的方法详解的文章就介绍到这了,更多相关JavaScript元素吸顶内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
js getBoundingClientRect使用方法详解
这篇文章主要介绍了js getBoundingClientRect使用方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下2019-07-07JS中的hasOwnProperty()、propertyIsEnumerable()和isPrototypeOf()
这篇文章主要介绍了JS中的hasOwnProperty()、propertyIsEnumerable()和isPrototypeOf()的相关资料,需要的朋友可以参考下2016-08-08Google (Local) Search API的简单使用介绍
这篇文章主要介绍了Google (Local) Search API的简单使用。需要的朋友可以过来参考下,希望对大家有所帮助2013-11-11用js脚本控制asp.net下treeview的NodeCheck的实现代码
根据TreeView2.js修改后的TreeView父节点与子节点的CheckBox联动.2010-03-03
最新评论