vue实现吸顶、锚点和滚动高亮按钮效果
因公司后台管理系统很多功能技术老旧,最近在用vue重构公司的后台管理系统,在做商品管理添加商品这一块,借鉴淘宝的添加商品的交互,需要实现一个简单的吸顶、锚点和滚动高亮按钮的效果。
需求
- 滚动页面到顶部,实现某元素固定到顶部效果
- 点击某个按钮,页面滚动到相应的位置
- 滚动页面,当到达某个位置时,高亮对应的相关按钮
元素吸顶实现方式
关于元素吸顶效果,通过查阅相关资料和相关测试,有三种方式(还有一种是jquery的方法,这里就不介绍了)
一、使用position:sticky
1. 什么是position:sticky?
粘性定位元素相当于position:relative和position:sticky的结合体,受限于父级元素,在不同的条件下呈现出不同的页面效果
2. 如何使用sticky?
sticky元素效果完全受限于父级元素,使用条件
1.sticky元素的父元素的overflow只能设置为visible,否则会导致没有粘滞效果
2.sticky元素的父元素不能设置固定的高度,否则会导致没有粘滞效果
3.sticky满足条件变成fixed定位时,与标准fixed元素不一样,不会脱离文档流
4.sticky 定位的元素不能添加一个只包含自身的父元素,会导致没有粘滞效果
5.同一个父级元素中的sticky元素,如果定位值相等,则会重叠,如果属于不同父级元素中,则会挤掉之前的元素,形成依次占位的效果 具体实现效果如下
.sticky-box{ position: sticky; position: -webkit-sticky; : 60px; //可通过js动态设置 }
3.兼容性
通过查看can i use 可以看到相关的兼容性
可以看出这个属性的兼容性不是那么好,如果项目需要兼容到ie11等的话,就不是那么适用了
二、使用offsetTop
HTMLElement.offsetTop 为只读属性,它返回当前元素相对于其 offsetParent 元素的顶部内边距的距离。我们需要注意的是,在监听页面滚动的过程中,需要将定位父级元素的偏移量也计算在内,可以如下写法
//获取当前元素的offsetTop getOffsetTop(obj) { let offsetTop = 0; while (obj != window.document.body && obj != null) { offsetTop += obj.offsetTop; obj = obj.offsetParent; } return offsetTop; }
通过在vue的mounted生命周期函数中添加监听事件滚动的事件
mounted() { /通过给变成固定定位的元素添加一个同等高度的父元素,防止该元素变成固定定位时,脱离文档流导致的页面抖动 / this.tabsHeight = this.$refs.elTabs.offsetHeight; window.addEventListener("scroll", this.handleScroll); }, destroyed() { //离开该页面需要移除这个监听的事件 window.removeEventListener("scroll", this.handleScroll); }, methods: { /滚动事件 / handleScroll() { //获取页面滚动条的高度 let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; let offsetTop = this.getOffsetTop(this.$refs.elTabs); this.isFixed = scrollTop > offsetTop; } }
如果这种吸顶方式在项目中会多次用到,就可以封装成组件的形式
三、使用getBoundingClientRect().
还有一种更为直接的方式,可以实现吸顶效果,就是使用getBoundingClientRect().来获取元素相对于视口(浏览器窗口)的位置,相对于offsetTop,该方法不用考虑到吸顶元素的父级元素和页面滚动条的高度,直接对该元素进行处理即可,实现如下 / 滚动事件 / handleScroll() { / getBoundingClientRect().
获取某元素距离浏览器顶部的高度,不包含滚动的距离 / let tabOffsetTop = this.$refs.stickyBox.getBoundingClientRect().; this.isFixed = tabOffsetTop < this.offsetTop }
/滚动事件 / handleScroll() { / getBoundingClientRect(). 获取某元素距离浏览器顶部的高度,不包含滚动的距离 this.offsetTop 表示的是吸顶元素距离顶部的条件值(一般项目需求是0) / let tabOffsetTop = this.$refs.stickyBox.getBoundingClientRect().; this.isFixed = tabOffsetTop < this.offsetTop }
锚点定位
点击相应的按钮,页面滚动到相应的位置,目前我知道实现该功能的方式有两种
1. 使用a标签定位 2. 使用js模拟锚点定位
使用a标签定位
这是一种常见的定位方式,它有两种实现方式
1. 通过href属性链接到指定元素的id
2.另一种是添加一个 a 标签,再将 href 属性链接到这个 a 标签的 name 属性
<a href="#view1">按钮1</a> <a href="#view2">按钮1</a> <div id="view1">视图1</div> <div><a name="view2">视图2</a></div>
这种定位方式很简单,支持任意标签的定位,a标签的定位会改变路由的hash,如果有相关路由会进行路由跳转
使用js模拟锚点定位
通过js获取元素的scrollTop值,使其滚动到指定的位置,就能实现锚点定位效果,这里的tab切换选项,用到是的element-ui的el-tabs组件,具体实现如下
<!-- html --> <el-tabs v-model="activeName" type="card" @tab-click="tabClick"> <el-tab-pane :label="item.name" :name="item.key" v-for="item in tabList" :key="item.key"></el-tab-pane> </el-tabs> <!-- js --> methods:{ //获取当前元素的offsetTop getOffsetTop(obj) { let offsetTop = 0; while (obj != window.document.body && obj != null) { offsetTop += obj.offsetTop; obj = obj.offsetParent; } return offsetTop; }, <!--锚点点击事件--> <!--fixedHeight 滚动的位置上方固定的高度--> tabClick(e) { let _this = this; //获取当前选中的index以便后面滚动高亮 this.index = parseInt(e.index); //给定一个标识,锚点事件不触发滚动 this.isScroll = false; this.isChange = false; //获取当前选中元素的值(给元素绑定对应的ref值) let offsetTop = this.getOffsetTop(this.$refs[this.activeName]); let scrollTop = offsetTop - this.fixedHeight; window.scrollTo({ : scrollTop }); }
不得不提的一个方法就是scrollIntoView,Element.scrollIntoView() 方法让当前的元素滚动到浏览器窗口的可视区域内,还支持动态效果,不支持配置滚动到距离顶部的距离,会出现遮罩现象,很适合做会到顶部的功能
滚动高亮按钮
当用户滚动内容区时,高亮距离按钮组件最近的那个元素所对应的按钮。 通过监听滚动事件,获取当前选中的tab的offsetTop值和当前页面的scrollTop值,判断向上或者向下滚动,做出不同的处理,具体如下
//页面滚动要做的事情 handleScroll() { let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; this.scrollTop = scrollTop; <!--isScroll 用于避免锚点事件触发页面滚动--> if (!this.isScroll) return; / scrollTop 页面的滚动条的高度 offsetTop 当前选中的tab元素的offsetTop offsetHeight 当前选中元素的高度 / let offsetTop = this.getOffsetTop(this.$refs[this.activeName]); let offsetHeight = this.$refs[this.activeName].offsetHeight; let actuaTop = scrollTop + this.fixedHeight; let length = this.tabList.length; / 页面滚动中根据相应位置变换选中tab / if (actuaTop < offsetTop && this.index > 0) { this.index = this.index - 1; this.activeName = this.tabList[this.index].key; } else if (this.index < length && actuaTop > offsetTop + offsetHeight) { this.index = this.index + 1; this.activeName = this.tabList[this.index].key; } }
性能优化
页面中读取属性会导致页面reflow(下次会对导致页面reflow和repaint 的操作做一个),过度的reflow会导致页面性能下降,所以我们应该尽量减少reflow的次数,以便给用户更好的体验。 如果产品可以接受效果有延迟,就可以使用节流函数控制在一定时间内只执行一次函数(节流函数可以使用lodash.js 封装好的 throttle 方法)
写到这里,需求中的三个功能都已经实现,也许还存在更好的方案,通过这次实现这三个需求,如果大家有其他更好的方法,欢迎留言补充,但我也从中学习到了一些东西 1.positionsticky的用法和使用条件
2.scrollTop、offsetTop等元素的相关属性、getBoundingClientRect()用法和 scrollTo、scrollIntoView的用法 3.锚点时间和滚动高亮事件导致的冲突处理等
以上所述是长沙网络推广给大家介绍的vue实现吸顶、锚点和滚动高亮按钮效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,长沙网络推广会及时回复大家的。在此也非常感谢大家对狼蚁SEO网站的支持!
如果你觉得本文对你有帮助,欢迎网络推广网站推广转载,烦请注明出处,谢谢!
编程语言
- 如何快速学会编程 如何快速学会ug编程
- 免费学编程的app 推荐12个免费学编程的好网站
- 电脑怎么编程:电脑怎么编程网咯游戏菜单图标
- 如何写代码新手教学 如何写代码新手教学手机
- 基础编程入门教程视频 基础编程入门教程视频华
- 编程演示:编程演示浦丰投针过程
- 乐高编程加盟 乐高积木编程加盟
- 跟我学plc编程 plc编程自学入门视频教程
- ug编程成航林总 ug编程实战视频
- 孩子学编程的好处和坏处
- 初学者学编程该从哪里开始 新手学编程从哪里入
- 慢走丝编程 慢走丝编程难学吗
- 国内十强少儿编程机构 中国少儿编程机构十强有
- 成人计算机速成培训班 成人计算机速成培训班办
- 孩子学编程网上课程哪家好 儿童学编程比较好的
- 代码编程教学入门软件 代码编程教程