首页 > 其他分享 >记录--移动端 H5 Tab 如何滚动居中

记录--移动端 H5 Tab 如何滚动居中

时间:2024-01-20 18:23:43浏览次数:47  
标签:distance 滚动 容器 -- H5 Item 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

公式的伪代码实现

现在开始解释公式的代码实现。

先看下 itemOffsetLefthalfItemWidthhalfScreenWidth 如何获取。

  • 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

Tab 滚动居中 | Vue

React

Tab 滚动居中 | React

微信小程序

Tab 滚动居中 | 微信小程序

小程序的 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

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 

标签:distance,滚动,容器,--,H5,Item,Tab,屏幕
From: https://www.cnblogs.com/smileZAZ/p/17976920

相关文章

  • P4747 [CERC2017] Intrinsic Interval 题解
    题目链接:IntrinsicInterval讲讲析合树如何解决这种问题,其实这题很接近析合树的板题的应用。增量法进行析合树建树时,需要用ST表预处理出\(max\)和\(min\)以便\(O(1)\)查询极差,然后线段树去维护\([l,r]\)上的极差减区间端点做差即\(diff-(r-l)\),当这玩意等于\(0\)时......
  • SP2150
    不难想到,求区间和可以先\(O(n)\)预处理前缀和,后面就能做到对于区间\([l,r]\)可以\(O(1)\)求出\(\sum_{i=l}^ra_i\)。接下来考虑如何求解答案。设预处理后的前缀和数组\(sum_i=\sum_{j=1}^ia_j\)。区间\([l,r]\)满足要求,当且仅当\(sum_r-sum_{l-1}=47\)成立。将上......
  • std::declval 元函数
    declval用于非求值上下文中declval原形:template<typename_Tp>autodeclval()noexcept->decltype(__declval<_Tp>(0)){static_assert(__declval_protector<_Tp>::__stop, "declval()mustnotbeused!");return__declval&l......
  • 相似单词记忆表
    相似单词记忆Aalone:独自,单独,孤独地,只along:沿着,顺着,向前,与...一起appear:出现,起源,问世,似乎,好像disappear:消失,失踪attract:吸引,引起attractive:有吸引力的,漂亮的Bbelow:在...下面lower:下面的,把...放低beat:打败,难过,胜过heat:热,热度heart:心脏,内心,重点,中央,心形Cchange:改......
  • LG9837
    蒟蒻太菜了,看不懂图论的做法,就只好找规律了。分析题目,可以得到一些信息:\(n\)个不同的数最多能组成\(\dfrac{n(n-1)}{2}\)个不相同的无序二元组,而一个$n\timesn$的下三角形同行相邻的数对数量为\(\dfrac{n(n-1)}{2}\),因此可以确定每个无序二元组必须恰好用一次。观察二......
  • LG10026
    看完题目后,发现直接对\(a\)模拟操作的情况过多,不好处理。但如果对\(n\)进行逆向操作,似乎可以在很少步数内就变为\(1\)。我们大胆猜想,用最少的步数使\(n\)变为\(1\),再考虑如何处理多余的次数(若次数不足则直接无解)。先列出转换后的操作:\(n\getsn+1\);\(n\getsn\div2......
  • 顺气丸
    顺气丸有哪几种医生头像医生标识杨波副主任医师中西科中南大学湘雅医院三甲|全国第15去咨询百度健康内容审核团队优选 顺气丸的主要功效是调理人体脏腑气机,对气机不畅引起的疾病有治疗作用。其常见种类包括木香顺气丸、开胸顺气丸、开郁顺气丸等。1、木香顺气丸:木香......
  • AT_abc179_e
    题意定义\(f(x,m)=x\bmodm\)。有一个序列\(a\),满足\(a_1=1\),\(a_i=f(a_{i-1}^2,m)\)。求\[\sum_{i=1}^na_i\]思路这道题\(n\)的数据范围很大,但\(m\)最多只有\(10^5\),因此考虑以此为突破口。需要用到如下的同余性质:\[(a\timesb)\bmodm=(a\bmodm\times......
  • CF1569C
    这题是个分类讨论题。要使得没有人连续两次提议,关键在于最大值和次大值。因此分三类情况。记最大值为\(a\),出现次数\(cnta\),次大值\(b\),出现次数\(cntb\)。\(cnta\ge2\)最大值不止一个,说明有多个人会同时在第\(a\)轮结束,因此无论任何情况都不会有人连续两次提议。......
  • AT_abc180_d
    贪心思想,STR值增长得越慢,可能得到的EXP值就越多。根据此,我们在\(x\)较小时,可以乘\(a\)也可以加\(b\),选择运算后较小的一种情况。在某一时刻,当\(x\timesa>x+b\)时,可知一直到最后都应选择加\(b\)(前者是几何级增长,后者是算术级增长)。然后计算能加的次数即可。具体......