写点什么

基于 Vue 的两层吸顶踩坑总结

2021 年 3 月 05 日

基于 Vue 的两层吸顶踩坑总结

前言


近日,在做活动页的过程中遇到两层吸顶的需求,并且要兼容 IE9 及以上的浏览器。乍一看不就是个吸顶嘛,应该不难吧,事实证明还是踩了很多坑才出来。兼容性问题多到吐血,我太难了。废话不多说,先看一下两层吸顶的最终实现效果,如下图所示。



功能点:两层吸顶,因为 Tabs 区域比较长所以在滚动过程中点击一层 Tabs 会回弹至一层吸顶刚吸顶的位置,这个功能点和锚点有些类似。二层 Tabs 通过 hover 切换,没有回弹效果。


实现方式


本文主要通过  VueSticky  插件来实现吸顶,实现步骤描述如下:


  • 安装:npm install vue-sticky --save

  • 引入:   import VueSticky from "vue-sticky"

  • 使用:

directives: {    'sticky': VueSticky,},
复制代码


<ELEMENT v-sticky="{ zIndex: NUMBER, stickyTop: NUMBER, disabled: [true|false]}">  <div><!-- sticky wrapper, IMPORTANT -->    CONTENT  </div></ELEMENT>
复制代码


看了  VueSticky  的源码后将该插件的实现原理简要概括如下:


首先判断该浏览器是否支持  position:sticky;,若支持就用  position:sticky;  来实现,若不支持就用  position:fixed;  的方式实现。所以大家不用担心兼容性问题,因为我已经帮大家测试过了,IE9 及以上的浏览器都可以支持。


生效条件


需要注意的是,使用 v-sticky 有几个必要条件,否则会失效:


  • 父元素不能设置  overflow:hidden  或者  overflow:auto  属性

  • 至少指定 top 、bottom 、left 、right  4  个值中的一个,否则只会处于相对定位

  • 父元素的高度不能低于 sticky 元素的高度

  • sticky 元素仅在其父元素内生效


问题汇总

◎ 吸顶“叠罗汉”


吸顶元素在滚动到组件底部时,在谷歌、火狐等浏览器中,两层吸顶在消失过程中有重叠现象,具体现象如下图所示:



主要原因:第一层吸顶还符合吸顶条件,第二层吸顶已经开始消失解决方案:给第一层吸顶元素添加  minHeight  属性,其大小为第一层吸顶元素的高度与第二层吸顶元素的高度的和。这里有一个需要注意的点在于:一开始第一层吸顶元素的高度并非两者之和,所以这里就需要监听滚动事件,在吸顶元素距离底部的距离为两者高度之和的位置处给第一层吸顶元素添加   minHeight  属性


以下代码块中,sumHeight 表示两个吸顶元素的高度和,initialHeight 表示的是第一层吸顶元素的高度


const offsetTop = document.querySelector(".xxx").offsetBottom;  if (offsetBottom <= sumHeight) {      document.querySelector(".xxx").style.minHeight = sumHeight;  } else {      document.querySelector(".xxx").style.minHeight = initialHeight;  }
复制代码

◎ 吸顶“舍不得离开”


在 IE 浏览器中,吸顶元素滚动到组件底部时不消失,具体现象如下图所示



主要原因:在滚动过程中吸顶元素的 position:sticky; 属性始终存在

解决方案:监听滚动事件,当滚动到组件底部时,将 v-sticky="{ stickyTop: 0, disabled: false }" 中的 disabled 的值设为 true 即可


◎ 吸顶“难舍难分”


在 IE 浏览器中,两层吸顶元素始终吸在一起



主要原因:第二层吸顶元素在不需要吸顶的区域,它的 position 值也为 sticky

解决方案:监听滚动事件,在不需要吸顶的区域设置它的 position 值为 static 即可


◎ 吸顶“变形”


同样 DOM 结构的吸顶元素,在 IE 浏览器中,吸顶会变形

查看 vue-sticky 的源码,发现 position:fixed; 是设置在要吸顶的元素的第一个子元素上



因此为了兼容 IE 需要多加一层 div 结构


<div v-sticky="{ stickyTop: 0, disabled: false }">    <div><!-- sticky wrapper, IMPORTANT -->        content    </div></div>
复制代码


注意事项


  • 组件的监听与移除

mounted() {    // handleScroll 为页面滚动的监听回调    window.addEventListener('scroll', this.handleScroll);},beforeDestroy() {    removeEventListener("scroll", this.handleScroll);},
复制代码


  • 同时要在 destroy 回调中移除监听

  • 在 mounted 回调中加入以下代码


优化点


  • 用监听事件监听滚动时,吸顶消失的很突兀


let supportCSSSticky = document.querySelector(".xxx").style.position === "sticky";if (!supportCSSSticky) {    // 不支持的情况下监听滚动}
复制代码


  • 判断浏览器是否支持 sticky ,若支持用 position:sticky; 实现,否则用 position:fixed;

  • 图片懒加载

  • 对于图片过多的页面,为了加速页面的加载速度,我们需要将页面内未出现在可视区域内的图片先不做加载, 等到滚动到可视区域后再去加载。

总结


本文简单的介绍了 VueSticky  插件的实现原理并分享了实战过程中出现的问题以及解决方案,希望对大家有所帮助。



头图:Unsplash

作者:Healer

原文:https://mp.weixin.qq.com/s/GatlX-hCh5f0YfXDy3sdrw

原文:基于 Vue 的两层吸顶踩坑总结

来源:政采云前端团队 - 微信公众号 [ID:Zoo-Team]

转载:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2021 年 3 月 05 日 23:441498

评论

发布
暂无评论
发现更多内容

netty案例,netty4.1中级拓展篇一《Netty与SpringBoot整合》

小傅哥

Java Netty

netty案例,netty4.1中级拓展篇三《Netty传输Java对象》

小傅哥

Java Netty 小傅哥

实战 | Vue + Element UI 页面创建

简爱W

Java 架构师

没有亮点的简历,要用详历来弥补

escray

学习 面试 简历 面试现场

netty案例,netty4.1基础入门篇二《NettyServer接收数据》

小傅哥

Java Netty 小傅哥

在java中使用SPI创建可扩展的应用程序

程序那些事

Java spi 可扩展程序 可扩展应用

理论 | 三天两夜,万字长文,吃透TCP/IP

简爱W

Java TCP

netty案例,netty4.1基础入门篇五《NettyServer字符串编码器》

小傅哥

Java Netty

netty案例,netty4.1基础入门篇十《关于ChannelOutboundHandlerAdapter简单使用》

小傅哥

Netty 小傅哥

netty案例,netty4.1中级拓展篇二《Netty使用Protobuf传输数据》

小傅哥

Java Netty 小傅哥

PHP浮点数精度损失问题

架构精进之路

php 弱类型语言

netty案例,netty4.1基础入门篇零《初入JavaIO之门BIO、NIO、AIO实战练习》

小傅哥

Java Netty 小傅哥

netty案例,netty4.1基础入门篇九《自定义编码解码器,处理半包、粘包数据》

小傅哥

Java Netty

netty案例,netty4.1基础入门篇一《嗨!NettyServer》

小傅哥

Java Netty

netty案例,netty4.1基础入门篇三《NettyServer字符串解码器》

小傅哥

Java Netty 小傅哥

netty案例,netty4.1中级拓展篇五《基于Netty搭建WebSocket,模仿微信聊天页面》

小傅哥

Java Netty 小傅哥

[租房]刚步入社会的小萌新,休想坑小妹妹,安排!

我是程序员小贱

LeetCode题解:11. 盛最多水的容器,for循环双指针,JavaScript,详细注释

Lee Chen

LeetCode 前端进阶训练营

netty案例,netty4.1基础入门篇八《NettyClient半包粘包处理、编码解码处理、收发数据方式》

小傅哥

Netty 小傅哥

netty案例,netty4.1基础入门篇十一《netty udp通信方式案例Demo》

小傅哥

Java Netty

netty案例,netty4.1中级拓展篇六《SpringBoot+Netty+Elasticsearch收集日志信息数据存储》

小傅哥

Java Netty

netty案例,netty4.1中级拓展篇七《Netty请求响应同步通信》

小傅哥

Java Netty 小傅哥

Stream 流

HeGuang

Java

netty案例,netty4.1基础入门篇六《NettyServer群发消息》

小傅哥

Java Netty 小傅哥

一把年龄,技术一般,怎么去面试

escray

学习 面试 面试现场

世界很大,我想去看看

escray

学习 面试 面试现场

netty案例,netty4.1基础入门篇四《NettyServer收发数据》

小傅哥

Java Netty 小傅哥

netty案例,netty4.1基础入门篇七《嗨!NettyClient》

小傅哥

Netty 小傅哥

netty案例,netty4.1基础入门篇十二《简单实现一个基于Netty搭建的Http服务》

小傅哥

Java Netty

netty案例,netty4.1中级拓展篇四《Netty传输文件、分片发送、断点续传》

小傅哥

Netty 小傅哥

程序开发中的持续集成、持续交付、持续部署

石云升

持续集成 持续交付 持续部署 自动化部署

「中国技术开放日·长沙站」现场直播

「中国技术开放日·长沙站」现场直播

基于 Vue 的两层吸顶踩坑总结-InfoQ