vue - vue项目中解决 IOS + H5 滑动边界橡皮筋弹性效果

news2024/12/25 9:35:58

问题:

最近遇到一个问题,我们在企业微信中的 H5 项目中需要用到table表格(支持懒加载 上划加载数据)。但是他们在锁头、锁列的情况下,依旧会出现边界橡皮筋效果。就会显示的很奇怪。

什么是ios橡皮筋效果:

我们知道元素超出所给定的高度会出现滚动条 | 横向的或纵向的,在ios手机上当在全局范围或局部范围出现滚动的地方时,滑动使滚动到头时还可以继续拖拽出一段距离的空白,松开手时立刻回弹回去。虽不影响功能,但是操作有点别扭,感觉这个table表格滑动的时候像是飘着上面的,不是固定的。

尝试思路:

针对这个问题我也尝试了不同的方案都不尽人意;
1,首先想到先使用css解决,前后使用了绝对定位和固定定位来提高层级,发现问题依然存在;
2,然后是用css属性&::-webkit-scrollbar { display: none;} 来隐藏滚动条 ,还是不行,
3,后面引入网上的inobounce插件还是不行。此插件会禁用页面的touchmove事件,导致页面无法进行滑动;
4,因为我用的是原生的table来布局的,难道是table标签的问题,后面我又重新用div来实现table表格的布局,发现还是会出现橡皮筋效果,说明不是标签的问题,是ios浏览器隐藏的特性;

解决方案:

最后我想到,既然我关不掉,那我自己完全控制滑动好了;原理是禁用掉页面touchumove的默认的滑动效果,使用元素的scrollLeft 和scrollTop这两个原生的可写属性,来进行元素的上下和左右移动;
这样做的好处在于,我自己完全控制了拖拽滑动行为。坏处在于丢失了原生滑动的惯性滑动,看着没那么丝滑了。不过这点也可以后续通过 JavaScript 来优化(暂时还没写 ,写出来的效果不太好,不丝滑)。

效果图如下:
可以上下左右滑动,是固顶的,向上滑动时标题部分不会跟随移动;
可以懒加载:当下滑到触底时会向父元素传递一个事件告诉父组件该请求下一页的数据了;
在这里插入图片描述
主要实现代码如下:

表格组件部分代码如下:tableStrick.vue;

  data() {
   return {
      listEle: null, // dom元素
      // 记录坐标
      touchX: "",
      touchY: "",
      // 滑动坐标
      startX: 0,
      startY: 0,
      // 滑动方向
      direction: "",
    };
  }

  mounted() {
    /* 获取dom元素 这里最好不要用原生的dom获取方式 */
    this.listEle = this.$refs.main;
    /* 自己实现滚动效果 不会出现滚动回弹问题 但是滚动不丝滑了且没有惯性 */
    this.listEle.addEventListener("touchstart", this.touchstart, false);
    this.listEle.addEventListener("touchmove", this.touchmove, false);
    this.listEle.addEventListener("touchend", this.touchend, false);
  },
  methods:{
    /* 修改 浏览器默认的滑动容器行为 */
    // 1,手指接触屏幕
    touchstart(event) {
      this.touchX = event.changedTouches[0].clientX;
      this.touchY = event.changedTouches[0].clientY;
      // 获取此刻手指的横坐标startX和纵坐标startY
      this.startX = event.touches[0].pageX;
      this.startY = event.touches[0].pageY;
    },
    // 2, 手指滑动的过程
    touchmove(event) {
      event.preventDefault();
      // 计算手指偏移量
      const offsetX = event.changedTouches[0].clientX - this.touchX;
      const offsetY = event.changedTouches[0].clientY - this.touchY;

      // 触摸的坐标
      this.touchX = event.changedTouches[0].clientX;
      this.touchY = event.changedTouches[0].clientY;

      // 手指滑动的方向 
      let moveEndX = event.changedTouches[0].pageX;
      let moveEndY = event.changedTouches[0].pageY;
      let X = moveEndX - this.startX;
      let Y = moveEndY - this.startY;
      // 注意 上下移动只能是上划或下划  左右移动也是同理
      if (Math.abs(X) > Math.abs(Y) && X > 0) {
        // 开始移动
         console.log('我向右滑了)
        this.listEle.scrollLeft = this.listEle.scrollLeft - offsetX;
        this.direction = "right";
      } else if (Math.abs(X) > Math.abs(Y) && X < 0) {
       	console.log('我向左滑了)
        this.listEle.scrollLeft = this.listEle.scrollLeft - offsetX;
        this.direction = "left";
      } else if (Math.abs(Y) > Math.abs(X) && Y > 0) {
      	console.log('我向下滑了)
        this.listEle.scrollTop = this.listEle.scrollTop - offsetY;
        /* 设置滚动到底的处理 */
        this.scrollBottom(event);
        this.direction = "bottom";
      } else if (Math.abs(Y) > Math.abs(X) && Y < 0) {
      	console.log('我向上滑了)
        this.listEle.scrollTop = this.listEle.scrollTop - offsetY;
        this.direction = "top";
        /* 设置滚动到底的处理 */
        this.scrollBottom(event);
      } else {
        this.direction = "";
      }
    },
    // 3,手指离开屏幕
    touchend(event) {
      this.touchX = event.changedTouches[0].clientX;
      this.touchY = event.changedTouches[0].clientY;
      // TODO  此处可以进行优化滚动的惯性 暂未实现
    },
    // 监听滚动条  注意 scroll 可能是横向滚动条 也可能是纵向滚动条
    scrollBottom(event) {
      // 1,可视区域
      let clientHeight = this.listEle.clientHeight;
      // 2,滚动文档高度
      let scrollHeight = this.listEle.scrollHeight;
      // 3,此处相等说明:没有纵向滚动条  可能出现了横向滚动条 所以要忽略
      if (clientHeight == scrollHeight) {
        return;
      }
      // 4,已滚动的高度
      let scrollTop = parseInt(this.listEle.scrollTop);
      // 这里 -2 是为了控制误差
      if (scrollTop + clientHeight >= scrollHeight - 2) {
        console.log("滚动到底了");
        // 把事件传出去 父元素开始请求下一页的数据
        this.$emit("scrollBottom");
      }
    },

  }

上面代码讲解:

1,mounted里面获取表格元素或父元素,然后监听手指点击事件,移动事件,离开事件;
2,touchstart方法中记录坐标,touchmove使用 event.preventDefault();禁用掉原先的滑动效果,自己通过this.listEle.scrollLeft和this.listEle.scrollTop来进行移动;
3,注意:下面的代码的意思是先要计算滑动的方向,然后再进行向对应的移动,防止上下左右一起移动,导致移动时太过敏感导致表格一直抖动;
在这里插入图片描述
4,scrollBottom方法是懒加载的处理 ,如果需要的话可以加上;主要是判断上下滑动时距离是否触底,触底就让父组件请求数据。

最后注意:

最后需要注意的是需要使用了懒加载 :需要对父元素中的scrollBottom这个方法进行防抖设置,因为滑动到底部触底时存在多次连续触底的行为(比较灵敏),这样会同时执行多次scrollBottom这个方法;导致数据请求过多;
防抖可以使用lodash库里面的debounce方法;

使用如下:在mounted中对scrollBottom进行防抖 ,也可以对实际请求接口的 自定义方法 进行防抖,

mounted(){
  /* 设置接口防抖 */
    this.scrollBottom= _.debounce(this.scrollBottom, 500); 
}

通过 JavaScript 来优化滚动的惯性 ,这个如果小伙伴们有好的方法可以放到评论区里学习一下;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/349766.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为MateBook E Go电脑使用U盘怎么安装Win10系统?

华为MateBook E Go电脑使用U盘怎么安装Win10系统&#xff1f;有用户购买这款电脑之后&#xff0c;发现系统默认安装的电脑系统是Win11版本的。但是自己不习惯使用这个系统&#xff0c;所以想要去将系统重新安装到Win10来使用。那么要怎么去进行系统重装呢&#xff1f;一起来看看…

微服务门神-Gateway与Sentinel的集成

目录 引言 概述 集成Sentinel 限流维度 网关集成 Route维度 API分组 精准匹配 前缀匹配 正则匹配 自定义限流返回格式 转视频版 引言 书接上篇&#xff1a;微服务门神-Gateway过滤器Filter&#xff0c;讲完了解Gateway过滤器之后&#xff0c;接下来看下Gateway与…

免费常用IP归属地查询API

引言 因毕设需要&#xff0c;需要使用到根据IP地址查询归属地 经过百度查询&#xff0c;发现如下几个api可以尝试&#xff0c;本人决定使用最后一个api 免费常用IP归属地查询API ip-api.com 可切换显示语言 http://ip-api.com/json/117.136.12.79?langzh-CN {"status…

wodat:一款针对Windows Oracle数据库的渗透测试工具

关于wodat wodat是一款功能强大的针对Windows Oracle数据库的渗透测试工具&#xff0c;该工具基于C# .Net Framework开发&#xff0c;能够帮助广大研究人员对Windows平台下的Oracle数据库执行按摩全渗透测试任务。 注意&#xff1a;请在被授权执行安全测试的情况下使用该工具…

[Apache Hudi] 流转批的场景实践

文章目录1.EventTime计算原理2.案例使用2.1 Maven pom 依赖2.2 设置EventTime2.3 Flink API2.4 Flink SQL2.5 读取EventTime在某些业务场景下&#xff0c;我们需要一个标志来衡量hudi数据写入的进度&#xff0c;比如&#xff1a;Flink 实时向 Hudi 表写入数据&#xff0c;然后使…

vue2版本《后台管理模式》(中)

文章目录前言一、创建一个文件夹 utils 里面新增一个 setToken.js 文件(设置token验证&#xff09;二 、创建一个api文件夹 新增 service.js &#xff08;axios拦截器&#xff09;三、在api文件夹里 新增一个 api.js 来接收数据&#xff08;把api封装哪里需要某项数据直接引入就…

运维服务商低成本提升服务质量解决方案

在信息化高速发展的今天&#xff0c;网络建设的重要性不言而喻&#xff0c;更多客户选择将运维服务外包或托管给运维服务商&#xff0c;市场需求愈大竞争压力愈大&#xff0c;想要脱颖而出势必要优化自身提高服务质量&#xff0c;最好是低成本、大提升&#xff0c;nVisual助力渠…

饕餮 NFT 作品集来袭!

饕餮 NFT 作品集包含 Chili Game 创作的体验《饕餮》第一章中的角色。可以在 The Sandbox 农历新年活动期间&#xff08;01/18/23 至 02/28/23&#xff09;体验。 饕餮的故事植根于中国古代神话&#xff0c;主要灵感来自《山海经》&#xff0c;一个关于捉妖人「青蛙侠」的故事。…

ASEMI中低压MOS管18N20参数,18N20封装,18N20尺寸

编辑-Z ASEMI中低压MOS管18N20参数&#xff1a; 型号&#xff1a;18N20 漏极-源极电压&#xff08;VDS&#xff09;&#xff1a;200V 栅源电压&#xff08;VGS&#xff09;&#xff1a;30V 漏极电流&#xff08;ID&#xff09;&#xff1a;18A 功耗&#xff08;PD&#x…

神经网络基础部件-卷积层详解

前言 在全连接层构成的多层感知机网络中&#xff0c;我们要通过将图像数据展平成一维向量来送入模型&#xff0c;但这会忽略了每个图像的空间结构信息。理想的策略应该是要利用相近像素之间的相互关联性&#xff0c;将图像数据二维矩阵送给模型中学习。 卷积神经网络(convolu…

教育舆情监测方案有哪些,TOOM讲解教育舆情的应对与处理?

教育舆情方案是针对教育领域的舆情事件或问题而制定的应对方案。其主要目的是通过有效的信息收集、分析、处理和传播&#xff0c;帮助教育机构或相关组织及时掌握和应对公众舆论的发展趋势&#xff0c;维护良好的舆情形象和声誉&#xff0c;教育舆情监测方案有哪些&#xff0c;…

黑马Java后端项目实战--在线聊天交友

【课程简介】 越来越多的系统都有消息推送的功能&#xff0c;如聊天室、邮件推送、系统消息推送等&#xff1b; 要实现消息推送就需要服务端在数据有变化时主动推送消息给客户端&#xff0c;本次课程将带大家使用websocket实现消息推送。 【主讲内容】 1.方法&#xff1a;如…

ANR系列(二)——ANR监听方案之WatchDog

前言 ANR的监控在Android6.0之前可以通过监听文件data/anr/trace读取trace信息来分析&#xff0c;但从6.0之后就被禁止了。随着Android的发展&#xff0c;手机里的ANR越来越多&#xff0c;对ANR的监控方案也就五花八门。 WatchDog方案 WatchDog是个开源的框架&#xff0c;是…

大漠插件最新中文易语言模块7.2302

模块名称:大漠插件中文模块最新通用7.2302模块简介:大漠插件中文模块最新通用7.2302模块特色:原翻译:花老板完善命令备注:易生易世本人花费一个月时间才将命令完善了插件的备注说明.且用且珍惜去掉了大漠插件定制版类.因为没用.模块特色:什么是中文模块?大漠插件模块是由大漠类…

Java SPI 概念和应用实现

Java SPI 测试 Demo一.SPI 简介1.概念 SPI 与 API2.作用二.Jdk SPI 实现1.SPI 接口定义2.SPI 实现类定义3.SPI 配置4.测试三.SpringBoot SPI 实现1.引入 SpringBoot 依赖2.SpringBoot SPI 配置3.测试一.SPI 简介 1.概念 SPI 与 API SPI 全称&#xff1a;Service Provider Int…

Xshell连接阿里云服务器搭建网站

一、建设一个网站的基本要求 申请一个独立的域名申请一台云服务器ECS在服务器上安装网站环境&#xff0c;如&#xff1a;Apache发布网站内容至云服务器将第一步注册的域解析至云服务器的外网IP地址进行ICP备案 二、用户访问网站的过程 在浏览器上输入域名浏览器自动调用DNS&…

SPI(服务提供发现机制)简单使用

一、概述 SPI的英文全称是Service Provider Interface&#xff0c;是Java内置的一种服务提供发现机制。一般常用于一些框架或组件库的开发&#xff0c;我们最熟悉JDBC就应用到了SPI机制&#xff0c;并且在Spring、Dubbo中也大量应用了SPI机制。SPI机制是针对同一个接口采用不同…

质量小议18 -- 熵

未能深入理解其包含的物理意义&#xff0c;浅记于此&#xff0c;以求理解对抗有自然无序的过程。 熵&#xff0c;对系统无序程序的度量&#xff0c;表征系统混乱程度。系统总是由有序向无序&#xff0c;最后走向静寂。 关键词&#xff1a;1. 无序和混乱&#xff1b;2. 有序向无…

Java中static关键字和代码块的学习

本文介绍了Java中static关键字的使用,即静态成员变量和成员方法以及使用,静态与非静态成员变量和方法的对比总结 Java中的代码块介绍与最后结合代码块和构造方法后的初始化代码执行顺序的练习 static和代码块的学习三.认识static关键字1.static修饰成员变量2.static修饰成员方法…

GAMES101-计算机图形学入门 LEC4: TRANSFORMATION-3D

本节课程视频地址&#xff1a;https://www.bilibili.com/video/BV1X7411F744/?p4 补充上一节课的一个内容&#xff0c;旋转矩阵的逆矩阵是它的转置&#xff0c;也就是说有R−θRθ−1RθTR_{-\theta} R_\theta^{-1}R_\theta^TR−θ​Rθ−1​RθT​ 上节课讲了&#xff0c;…