4 种滚动吸顶实现方式的比较(2)

// html <div ref="pride_tab_fixed"> <div :class="titleFixed == true ? 'isFixed' :''"> // some code </div> </div> // vue export default { data(){ return{ titleFixed: false } }, activated(){ this.titleFixed = false; window.addEventListener('scroll', this.handleScroll); }, methods: { //滚动监听,头部固定 handleScroll: function () { let offsetTop = this.$refs.pride_tab_fixed.getBoundingClientRect().top; this.titleFixed = offsetTop < 0; // some code } } }

offsetTop 和 getBoundingClientRect() 区别

1. getBoundingClientRect():

用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置。不包含文档卷起来的部分。
该函数返回一个 object 对象,有6个属性:
top, right, buttom, left, width, height。
(在 IE 中,默认坐标从(2,2)开始计算,只返回 top,lef,right,bottom 四个值)

2. offsetTop:

用于获得当前元素到定位父级( element.offsetParent )顶部的距离(偏移值)。

定位父级 offsetParent 的定义是:与当前元素最近的 position != static 的父级元素。

offsetTop 和 offsetParent 方法相结合可以获得该元素到 body 上边距的距离。代码如下:

getOffset: function(obj,direction){ let offsetL = 0; let offsetT = 0; while( obj!== window.document.body && obj !== null ){ offsetL += obj.offsetLeft; offsetT += obj.offsetTop; obj = obj.offsetParent; } if(direction === 'left'){ return offsetL; }else { return offsetT; } }

延伸知识点

offsetWidth:

元素在水平方向上占用的空间大小:
offsetWidth =  border-left + padding-left + width + padding-right + border-right

offsetHeight:

元素在垂直方向上占用的空间大小:
offsetHeight =  border-top + padding-top + height + padding-bottom + border-bottom

注:如果存在垂直滚动条,offsetWidth 也包括垂直滚动条的宽度;如果存在水平滚动条,offsetHeight 也包括水平滚动条的高度;

offsetTop:

元素的上外边框至 offsetParent 元素的上内边框之间的像素距离;

offsetLeft:

元素的左外边框至 offsetParent 元素的左内边框之间的像素距离;

注意事项

所有偏移量属性都是只读的;

如果给元素设置了 display:none,则它的偏移量属性都为 0;

每次访问偏移量属性都需要重新计算(保存变量);

在使用的时候可能出现 DOM 没有初始化,就读取了该属性,这个时候会返回 0;对于这个问题我们需要等到 DOM 元素初始化完成后再执行。

遇到的两个问题

一、吸顶的那一刻伴随抖动

出现抖动的原因是因为:在吸顶元素 position 变为 fixed 的时候,该元素就脱离了文档流,下一个元素就进行了补位。就是这个补位操作造成了抖动。

解决方案
为这个吸顶元素添加一个等高的父元素,我们监听这个父元素的 getBoundingClientRect().top 值来实现吸顶效果,即:

<div ref="pride_tab_fixed"> <div :class="titleFixed == true ? 'isFixed' :''"> 使用 `obj.getBoundingClientRect().top` 实现 </div> </div>

这个方案就可以解决抖动的 Bug 了。

二、吸顶效果不能及时响应

这个问题是我比较头痛,之前我没有在意过这个问题。直到有一天我用美团点外卖的时候,我才开始注意这个问题。
描述:

当页面往下滚动时,吸顶元素需要等页面滚动停止之后才会出现吸顶效果
当页面往上滚动时,滚动到吸顶元素恢复文档流位置时吸顶元素不恢复原样,而等页面停止滚动之后才会恢复原样

原因:

在 ios 系统上不能实时监听 scroll 滚动监听事件,在滚动停止时才触发其相关的事件。
解决方案:
还记得第一种方案中的 position:sticky 吗?这个属性在 IOS6 以上的系统中有良好的兼容性,所以我们可以区分 IOS 和 Android 设备做两种处理。

IOS 使用 position:sticky,Android 使用滚动监听 getBoundingClientRect().top 的值。

如果 IOS 版本过低呢?这里提供一种思路:window.requestAnimationFrame()。

以上所述是小编给大家介绍的4种滚动吸顶实现方式的比较详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

您可能感兴趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/f1963eb0eba3a6fc52aa5c39b8bc0b04.html