vue实现置顶功能
需求背景:项目中需要将某个标题置顶,但element没有支持置顶的组件,所以手动实现(原生js),效果如下图:
1)解决思路:先找到当前页面,滚动条所在dom,然后添加滚动条监听事件,对比滚动条的高度和置顶内容的offsetTop高度,大于则开启置顶,小于则还原。
2)话不多说上代码
// 示例代码
1 <template> 2 <div class="main"> 3 <div class="title" :class="isSticky ? 'sticky-title' : '' " :style="{'margin-top': marginTop}"> 4 <div>置顶部分内容</div> 5 </div> 6 <div> 7 <div style="height: 300px;background-color: #6950a1">滚动展现的内容1</div> 8 <div style="height: 300px;background-color: #6950a1">滚动展现的内容2</div> 9 <div style="height: 300px;background-color: #6950a1">滚动展现的内容3</div> 10 <div style="height: 300px;background-color: #6950a1">滚动展现的内容4</div> 11 <div style="height: 300px;background-color: #6950a1">滚动展现的内容5</div> 12 </div> 13 </div> 14 </template> 15 <script> 16 let _that = null; 17 18 export default { 19 name: '', 20 data() { 21 return { 22 curDom: null, // 滚动条节点 23 isSticky: false, // 是否置顶 24 marginTop: 0 // 设置置顶部分外边距 25 } 26 }, 27 mounted(){ 28 this.$nextTick(() => { 29 this.stickyEvent(); 30 }) 31 }, 32 methods:{ 33 stickyEvent(){ 34 _that = this; 35 const myDom = Array.from(document.getElementsByClassName('title')); 36 if (myDom.length) { 37 this.offsetTop = myDom[0].offsetTop; // 置顶内容距离顶部的距离 38 } 39 // 找到滚动条所在节点,很关键,否则监听无效 40 const scrollDom = Array.from(document.getElementsByClassName('el-main')); 41 if (scrollDom.length) { 42 this.curDom = scrollDom[0]; 43 // 开启滚动监听 44 this.curDom.addEventListener('scroll', this.handleScrollEvent); 45 } 46 }, 47 // 滚动监听事件函数,注意this的指向问题 48 handleScrollEvent(){ 49 const scrollTop = _that.curDom.scrollTop; // 滚动条高度 50 if(scrollTop >= _that.offsetTop) { 51 // 开启置顶,计算位置 52 _that.isSticky = true; 53 _that.marginTop = _that.offsetTop + 'px'; 54 } else { 55 _that.isSticky = false; 56 _that.marginTop = 0; 57 } 58 } 59 }, 60 destroyed () { 61 // 离开页面,关闭监听,释放资源同时避免报错 62 this.curDom.removeEventListener('scroll', this.handleScrollEvent); 63 } 64 } 65 </script> 66 <style lang="scss" scoped> 67 .main { 68 width: 100%; 69 min-height: 700px; 70 } 71 // 高度,宽度,背景色根据需求,自行调整 72 .sticky-title { 73 z-index: 999; 74 position: sticky; 75 top: -2%; 76 background: #fff; 77 width: 100%; 78 } 79 </style>
只提供一种思路,如果不足之处多多交流指正,如有更好的解决方案,还望不吝指导。