记录--移动端 H5 Tab 如何滚动居中
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
移动端 H5 Tab 如何滚动居中
Tab 在 PC 端、移动端应用都上很常见,不过 Tab 在移动端 比 PC 端更复杂。为什么呢?移动端设备屏幕较窄,一般仅能展示 4 ~ 7 个 Item。考虑到用户体验,UI 往往要求程序员实现一个功能——点击 Item 后,Item 滚动到屏幕中央,拼多多的 Tab 就实现了这个功能。

如果你也想实现这个功能,看了这篇文章,你一定会有所收获。我会先说明 Tab 滚动的本质,分析出滚动距离的计算公式,接着给出伪代码,最后再给出 Vue、React 和微信小程序的示例代码。
Tab 滚动的本质
Tab 滚动,本质是包裹着 Item 的容器在滚动。
如下图,竖着的虚线长方形代表手机屏幕,横着的长方形代表 Tab 的容器,标着数字的小正方形代表一个个 Tab Item。
左半部分中,Tab 容器紧贴手机屏幕左侧。右半部分中,Item 4 位于屏幕中央,两部分表示 Item 4 从屏幕右边滚动到屏幕中央。

不难看出,Item 4 滚动居中,其实就是容器向左移动 distance。此时容器滚动条到容器左边缘的距离也是 distance。
换句话说,让容器向左移动 distance,Item 4 就能居中。 因此只要我们能找出计算 distance 的公式,就能控制某个 Item 居中。
计算 distance 的公式
该如何计算 distance 呢?我们看下方这张更细致的示意图。
屏幕中央有一条线,它把 Item 4 分成了左右等宽的两部分,也把手机屏幕分成了左右等宽的两部分。你可以把 Item 4 一半的宽度记为 halfItemWidth,把手机屏幕一半的宽度记为 halfScreenWidth。再把 Item 4 左侧到容器左侧的距离记为 itemOffsetLeft。

不难看出,这四个值满足如下等式:
distance + halfScreenWidth = itemOffsetLeft + halfItemWidth
简单推导一下,就得到了计算 distance 的公式。
distance = itemOffsetLeft + halfItemWidth - halfScreenWidth
公式的伪代码实现
现在开始解释公式的代码实现。
先看下 itemOffsetLeft、halfItemWidth 和 halfScreenWidth 如何获取。
itemOffsetLeft是 Item 元素到容器左侧的距离,你可以用 HTMLElement.offsetLeft 作它的值。halfItemWidth是 Item 元素一半的宽度。HTMLElement.offsetWidth 是元素的整体宽度,你可以用offsetWidth / 2作它的值,也可以先用 Element.getBoundingClientRect() 获取一个itemRect对象,再用itemRect.width / 2作它的值。halfScreenWidth是手机屏幕一半的宽度。 window.innerWidth 是手机屏幕的整体宽度,你可以用innerWidth / 2作它的值。
再看下如何把 distance 设置到容器上。
在 HTML 中,我们可以使用 Element.scrollLeft 来读取和设置元素滚动条到元素左边的位置。因此,你只需要容器的 scrollLeft 赋值为 distance,就可以实现 Item 元素滚动居中。
现在给出点击 tab 的函数的伪代码:
const onClick = () => {
const itemOffsetLeft = item.offsetLeft;
const halfItemWidth = item.offsetWidth / 2;
const halfScreenWidth = window.innerWidth / 2;
tabContainer.scrollLeft = itemOffsetLeft + halfItemWidth - halfScreenWidth
}
代码示例
Vue
React
微信小程序
小程序的 API 和浏览器的 API 有差异。
itemOffsetLeft,你需要从点击事件的event.currentTarget中获取。halfItemWidth,你需要先用wx.createSelectorQuery()选取到 Item 后,从exec()的执行结果中获取到 Item 整体宽度,然后再除以 2。halfScreenWidth,你需要先用wx.getSystemInfoSync()获取屏幕整体宽度,然后再除以 2。
至于把 distance 设置到容器上,微信小程序 scroll-view 组件中,有 scroll-left 这个属性,你可以把 distance 赋值给 scroll-left。
本文转载于:
https://juejin.cn/post/7322730720732921867
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

记录--移动端 H5 Tab 如何滚动居中的更多相关文章
- 移动端H5页面惯性滑动监听
移动端H5页面惯性滑动监听 在移动端,当你快速滑动有滚动条的页面时,当你手指离开屏幕时,滚动条并不会立即停止,而是会随着"惯性"继续滑动一段距离. 在做项目的过程中,需要监听惯性滑 ...
- Web端的Tab控件在切换Tab时Load数据出错的处理
我们在应用Web端的Tab控件时,不管是Jquery easyui的还是Ext的Tab控件都会遇到一个问题,在Tab1正在加载数据的时候我们切换到Tab2,再切换回来,Load数据的控件就会出错,出错 ...
- 移动端H5制作安卓和IOS的坑 持续更新...
移动端H5制作安卓和IOS的坑 持续更新... 前言:最近参加公司的H5页面创意竞赛,又遇到不少页面在不同系统上的坑.踩坑之余,觉得很多之前遇到的知识点都忘了,索性开一篇博文,把这些坑都统一归纳起来, ...
- 教你如何用 lib-flexible 实现移动端H5页面适配
前话 好久没写教程了(可能会误导新手的菜鸟教程( ̄▽ ̄)"). 这是我的github,欢迎前端大大们和我一起学习交流 https://github.com/pwcong 最近入职公司做前端实 ...
- 移动端H5活动页优化方案
背景 项目:移动端H5电商项目 痛点:慢!!! 初始方案:最基本的图片懒加载,静态资源放到cdn,predns等等已经都做了.但是还是慢,慢在哪? 显而易见的原因:由于前后端分离,所有的数据都由接口下 ...
- 移动端H5混合开发设置复盘与总结
此篇接上一篇: 移动端H5混合开发,Touch触控,拖拽,长按, 滑屏 实现方案 https://www.cnblogs.com/buoge/p/9346699.html app 场布设置已经上线了, ...
- 移动端H5适配方法(盒子+图片+文字)
一.怎么让H5页面适应手机 a.利用meta标签 <meta name="viewport" content="width=device-width,initial ...
- 六一广告页H5全屏滚动效果实现
明天就六一儿童了(放假了),在这里提前祝大家周末快乐,每逢节假日公司必然会推出h5活动页的需求,这次六一儿童节也不例外,产品这次倒是没提什么互动效果需求,只不过根据UI妹子给的设计图,图片与图片中颜色 ...
- 移动端H5开发遇到的问题及解决方法
本篇文章给大家带来的内容是关于移动端H5开发遇到的问题及解决方法,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 微信分享签名错误invalid signature vue单页应用hi ...
- 前端提升生产力系列三(vant3 vue3 移动端H5下拉刷新,上拉加载组件的封装)
| 在日常的移动端开发中,经常会遇到列表的展示,以及数据量变多的情况下还会有上拉和下拉的操作.进入新公司后发现移动端好多列表,但是在看代码的时候发现,每个列表都是单独的代码,没有任何的封装,都是通过v ...
随机推荐
- Python-字符串format方法指定参数
一.字符串的format方法有几种指定参数的方式:(1)按照位置传参(默认方式),传入的参数与{}一一对应(2)关键字传参,关键字(keyword)传递是根据每个参数的名字传递参数.关键字并不用遵守位 ...
- ABC 310
E \(dp[i][j]\) 表示前 \(i\) 个里有多少个后缀答案为 \(j\). \(if (c[i] == '0') \{\) \(dp[i][0] = 1;\) \(dp[i][1] = d ...
- CF1823D Unique Palindromes
题目链接 题解 知识点:构造. 首先反证法容易证明一个结论:每次增加一个字符,本质不同的回文子串至多增加一个. 那么无解的条件就是,\(c_i - c_{i-1} > x_i -x_{i-1}\ ...
- Python 中global 关键字理解
Python中的global关键字,你了解吗? 前言 今天来了解下 Python 中的 global 关键字. Python变量的作用域 实战案例演示之前,先要了解下 Python 的作用域. Pyt ...
- PCIE分层结构
PCIe分层结构 绝大多数的总线或者接口,都是采用分层实现的.PCIe也不例外,它的层次结构如下: PCIe定义了下三层(彩色部分):事务层(Transaction Layer),数据链路层(Data ...
- STC89C52驱动MAX7219LED点阵级联, 文字滚动效果
级联下的传值方式 级联下, N个MAX7219相当于组成了一个8*N bit宽度的锁存器, 如果需要对第M个7219进行写入, 需要做M次寻址+写入后拉高CS, 才能到达这个7219. 如果仅仅对这个 ...
- 两台redhat7虚拟机配置ssh免密访问
说明 有时候为了方便搭建各种集群环境,需要配置多台虚拟机之间可以互相免密码访问.本文就介绍一下这个知识点,希望所帮助的朋友给老徐点个赞:) 两台虚拟机环境配置如下: 虚拟机1:192.168.56.1 ...
- Spring Boot整合JWT实现接口访问认证
最近项目组需要对外开发相关API接口,需要对外系统进行授权认证.实现流程是先给第三方系统分配appId和appSecret,第三方系统调用我getToken接口获取token,然后将token填入Au ...
- std::vector<std::string> 与 char** 的转换
vecotr 容器中插入多条字符串,再将 vector 的地址转换为 char** 代码如下: #include <stdio.h> #include <string> #in ...
- sort.interface接口
一个内置的排序算法需要知道三个东西:序列的长度,表示两个元素比较的结果,一种交换两个元素的方式:这就是sort.Interface的三个方法: package sort type Interface ...
