「H5」三种滚动吸顶效果实现方案以及性能优化
2020/6/19 11:56:31
本文主要是介绍「H5」三种滚动吸顶效果实现方案以及性能优化,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
方案
滑动吸顶效果的常见实现方式有以下几种:
1.positon: sticky
2.监听元素的滚动事件,使用offset判断
3.obj.getBoundingClientRect().top
下面依次介绍
positon: sticky
postion: sticky
属性值是css3新加入的属性,近似于relative和fixed的结合体
sticky被称为粘性定位元素,postion属性值为sticky的元素在目标区域内时表现的和position: relative
时无异。
当元素满足粘性定位的要求时(如top: 100px
),他的表现与position: fixed
无异
元素固定的相对偏移是相对于离它最近的具有滚动框的祖先元素,如果祖先元素都不可以滚动,那么是相对于viewport来计算元素的偏移量。
使用条件:
- 父元素不能设置为
overflow:hidden/auto
- 如果要实现fixed的效果,必须要指定 top,bottom,right,left之一,不然其表现与relative无异
- 父元素的高度不能低于skicky元素的高度
坑:
- sticky元素是容齐相关的,它只在自己的符合条件的祖先容器内生效。
- sticky元素虽然在满足粘性条件时表现position: fixed 无异,但是并不会触发BFC
- sticky元素对于写在样式表中的z-index是无效的,如果想用z-index属性可以写在行内样式中
兼容性:
兼容性不太友善,ios虽然支持度还行但是刘海屏的表现暂时待定
使用方式:
.sticky{ positon: sticky; top: 10px } 复制代码
监听滚动事件——offset
首先来复习以下offset值的含义:
距离拥有相对定位的父级元素的顶部偏移量
那么offset并不一定表示元素距离页面顶部的距离,也可能是与拥有相对定位的父级元素的顶部距离
假设我们需要的吸顶效果是在body的顶部,我们可以如下改造一个方法
getOffset(obj,direction) { let offsetL = 0; let offsetT = 0; // 依次获取父级元素的offsetLeft/offsetTop while( obj!== window.document.body && obj !== null ){ offsetL += obj.offsetLeft; offsetT += obj.offsetTop; obj = obj.offsetParent; } if(direction === 'left'){ return offsetL; }else { return offsetT; } } handleScroll(e) { let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; let offsetTop = getOffset(e.target,'top'); if(scrollTop > offsetTop){ // fixed } } 复制代码
优势:兼容性优秀
劣势:存在性能问题,最好搭配节流函数使用
监听滚动事件——obj.getBoundingClientRect().top
定义:返回某个元素相对浏览器视窗上下左右的距离
也就是说,这个api完全可以取代上面那个函数...
兼容性:
优势:简 洁 , 兼 容 性 极 佳
劣势:没有解决reflow过多的性能问题
性能优化
众所周知,所有的scroll问题都逃不过高强度reflow带来的性能压力
解决方法也非常明确——牺牲平滑度,减少触发次数
throttle
在通常情况下,我们可以直接使用节流函数直接来限制触发次数,比如这么做
// 假设你封装好了一个throttle(func,time)的节流函数 window.addEventListener('scroll', throttle(handleScroll, 20)); 复制代码
但这么使用有一个问题。。那就是会出现吸顶时有一定卡顿的情况,就不够润。
那咋办呢?
我们不妨换种思路。。。不如精确控制handleScroll()函数的触发时机?
自然我们就想到了 IntersectionObserver API
IntersectionObserver API
IntersectionObserver API 的使用教程请移步这里
这个api的主要目的是用来判断一个元素是否在可视范围内(并可以控制触发时机)
兼容性:
不难发现还是有那么一点兼容性问题的。所以我们不如将throttle和IntersectionObserver 方案结合起来使用
结合方案
this.flag == false scrollFunc(e) { if( IntersectionObserver ){ const observer = new IntersectionObserver(function(){ const offsetTop = e.target.getBoundingClientRect().top; if(offsetTop < 0){ // 吸顶 this.flag == true }else{ this.flag == false } }, { // 100%时触发回调函数 threshold: [1] }); observer.observe(e.target); } else { window.addEventListener('scroll', throttle(()=>{ let offsetTop = e.target.getBoundingClientRect().top; if(offsetTop < 0){ // 吸顶 this.flag == true }else{ this.flag == false } }, 20)); } } 复制代码
这篇关于「H5」三种滚动吸顶效果实现方案以及性能优化的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南