网页元素固定定位及top值变化详解
本文分析一段关于菜单栏固定定位的代码,解释其top值在不同滚动状态下变化的原因。代码旨在使名为sidebarright的元素(一个
- 列表)在页面滚动超过其初始位置后,固定在距离顶部75px的位置。
-
场景一:页面轻微滚动,未超过sideBarRightTop: else代码块执行,sideBarRight.style.top被赋值为currentTop(空字符串)。在CSS中,空字符串会被解析为继承父元素的top值,因此显示为元素的初始top值(例如260px)。
-
场景二:页面滚动超过sideBarRightTop,然后又滚动回去: if代码块先执行,sideBarRight.style.top被设置为'75px'。之后,else代码块执行,sideBarRight.style.top被赋值为currentTop(仍然为空字符串)。然而,由于sideBarRight的定位模式已变为fixed,且top值之前已设置为'75px',因此空字符串不会覆盖这个值,sidebarright仍然保持在距离顶部75px的位置。
核心代码如下:
var sideBarRight = document.querySelector('.sideBar_right ul'); var sideBarRightTop = sideBarRight.offsetTop; var currentTop = ''; // 初始值为空字符串 document.body.onscroll = function() { var docScrollH = document.documentElement.scrollTop; if (docScrollH > sideBarRightTop) { sideBarRight.style.position = 'fixed'; sideBarRight.style.top = '75px'; } else { sideBarRight.style.position = 'absolute'; sideBarRight.style.top = currentTop; // 关键点 } };
currentTop变量值差异导致的问题:
代码中currentTop变量的初始值为空字符串。关键在于currentTop在不同情况下值的不同,导致sidebarright.style.top表现出差异:
并非null和undefined的区别,而是CSS和JavaScript交互的行为:
问题不在于null和undefined的类型区别,而在于:
-
JavaScript如何处理style.top属性的赋值: 当赋值为空字符串时,CSS会根据上下文进行解析,导致继承父元素的top值。
-
fixed和absolute定位模式下的行为差异: fixed定位的元素会相对于浏览器窗口进行定位,而absolute定位的元素则相对于其最近的已定位祖先元素进行定位。 fixed定位下,之前的top值会被保留,除非被明确覆盖。
-
空字符串在CSS中的含义: 空字符串表示继承父元素的属性值。
因此,更合理的代码应该在if代码块中保存当前的top值,并在else代码块中恢复该值:
var sideBarRight = document.querySelector('.sideBar_right ul'); var sideBarRightTop = sideBarRight.offsetTop; let currentTop = ''; document.body.onscroll = function() { var docScrollH = document.documentElement.scrollTop; if (docScrollH > sideBarRightTop) { currentTop = sideBarRight.style.top; // 保存当前top值 sideBarRight.style.position = 'fixed'; sideBarRight.style.top = '75px'; } else { sideBarRight.style.position = 'absolute'; sideBarRight.style.top = currentTop; // 恢复top值 } };
通过保存和恢复top值,可以避免由于空字符串导致的继承父元素top值的问题,确保元素在不同滚动状态下都能正确定位。