前言: 从最开始应用掘金之后,就对掘金 PC 端和 挪动端 的 Tab 栏的实现感到好奇。本人对于 页面滚动时要做出交互成果 始终是我单薄的中央。然而目前公司的我的项目外围都是以挪动端为主,如果不把握一些这部分常识,就无奈做出一些令人难受的交互逻辑。遂明天特意抽时间去学习了一下相干原理,这种成果的实现思路有很多,我只解说我学习到的一种形式。
咱们先预览最终效果图:
一. 剖析需要
- 咱们以 PC 端为例来剖析接下来要讲的内容。
- 能够分明的看到,首页顶部 Tab 随着咱们的滚动开始进行自动隐藏。
- 这是起始状态,页面未产生滚动,顶部只存在一个 Tab。
- 这是中间状态,在某一个时刻同时存在两个 Tab。
- 这是最终状态,随着页面滚动到某一个临界值,最初只留下了 头像 Tab。
二. 筹备工作
- 咱们先创立一个简略的能够滚动的场景。(你也能够间接在 源码 题目间接复制我的代码,前提是你也在应用 UnoCSS,如果你不分明 UnoCSS 的应用办法,那你能够点击上面这篇文章。)
🫱 🎁手把手教你创立本人的代码仓库) - 上面是咱们目前的状态,没有做任何对于滚动的响应式。
- 我置信大部分读者十分分明的晓得,当咱们页面产生滚动的时候,滚动的元素会触发一个
onScroll
事件,这个事件也是常常被拿来当 防抖和截流 的例子,然而明天咱们不思考 防抖和截流,咱们先用用这个事件是如何触发的。 - 你须要在你设置了
overflow-auto
的元素身上绑定一个回调函数,当页面产生滚动的时候,该函数就会被正确的触发,这也是咱们本文的重点。能够看到,当我滚动页面的时候,这个函数正在被触发,并且触发频率十分快。
三. scrollTop
- 这里你要晓得,当滚动事件触发的时候,该回调函数会被传递一个事件参数。
- 而 e 的
target
属性指的就是正在产生滚动的这个元素。 - 它身上有一个非常重要的属性,就是咱们明天的配角 scrollTop。咱们间接打印一下,看一下这个属性是如何变动的。
- 聪慧的你肯定很快就能发现,它其实就代表着咱们实际上滚动的间隔。说的更确切一点,它代表着咱们滚动元素间隔页面顶部的间隔。
- 既然咱们曾经晓得了页面理论滚动的间隔,咱们还晓得这两个 Tab 的具体高度,那么咱们就能够在适合的机会去操作这两个元素的属性,让它随之咱们的页面来做一些响应式的变动。
- 咱们先给这两个 Tab 取两个名字,并且打上对于的
ref
,因为接下来咱们要频繁的去操作这两个元素的款式。
四. 实现页面滚动响应式
- 回顾第一个状态,页面没有产生滚动,咱们的
avatar
标签是没有展现的。 - 咱们这里从新设计一下款式,切换咱们的
search
为sticky
,并且设置top-0
,使它一开始能够固定在咱们的页面顶部。而后再加一点点和avatar
的间距,待会咱们马上就要通过滚动实现一些成果。绝对应的页面成果如下:
- 这里其实咱们要用到一个障眼法,咱们须要给
search
栏设置一个兄弟元素,并且这个兄弟元素的属性恰好和咱们的avatar
栏是截然不同的。(指的是款式和性能一样)所以你当初的页面应该是上面这个样子。 - 首先明确的要晓得,头像栏 1 在最开始的没滚动到一临界值的时候是不会展现进去的。这里咱们之间给它设置一个
opacity-0
,让它的透明度是 0。 - 接下来干的事件就非常简单了,咱们这里再看一下掘金的成果。
这里咱们看到,在同一时间会同时存在两个框框,那么咱们滚动的最小值即可算进去。
依据上图咱们能够晓得,当咱们滚动
200px(margin-top)+ 70px
的时候,恰好search
和头像栏
的顶部接触。 - 那么此时咱们不做任何限度,持续往下
滚动头像栏 2
的高度70px
。那么页面此时恰好会把头像栏 2
遮挡住对吧?为了不便展现,我把scrollTop
的值贴上去了。(这里有些许误差,是我滚轮并不是特地容易滚动到那个数值。)
五. 实现顶部过渡切换
- 这里咱们须要加一个变量
isShow
,并且咱们把 头像栏 2 的透明度款式设置:style
的模式使之能够动静的切换。此时的页面成果应该是这样:
- 能够看到当咱们页面滚动到齐全看不到 头像栏 2 的时候,咱们只须要让 头像栏 1 的透明度变为 1 即可实现相似于坑骗用户眼睛的感觉,如同 头像栏 2 又贴着回来了。
- 此时还差最初的一步,
search
栏上移,只展现 头像栏 1 。 - 那么接下来要做的事件十分非常简单,就是让搜寻栏在此时往上挪动本身高度即可。
成果如下:
- 嗯 … 成果有些许僵硬,咱们加一个简略的过渡,让
search
隐没的不那么僵硬。最终成果如下:
六. 源码
<script setup lang="ts">
import {ref} from "vue";
const scrollTop = ref<number>(0);
const isShow = ref<boolean>(false);
function scroll(e: any) {
scrollTop.value = e.target.scrollTop;
if (scrollTop.value > 280) isShow.value = true;
else isShow.value = false;
}
</script>
<template>
<div
@scroll="scroll"
class="w-[390px] relative h-[500px] flex itmes-center bg-blue m-x-auto overflow-scroll"
>
<div class="fixed z-[999999] top-0 right-390px text- text-[20px]">
{{scrollTop}}
</div>
<div class="relative w-full h-5000px flex flex-col">
<div
class="sticky w-full"
:style="[isShow ? { top: '-50px'} : {top: 0},
{transition: `all 1s`},
]"
>
<div ref="search" class="h-50px bg-red leading-50px">
<span> 搜寻栏 height:50px</span>
</div>
<div
class="h-70px bg-black leading-70px"
:style="isShow ? {opacity: 1} : {opacity: 0}"
>
<span class="text-white"> 头像栏 1 height:70px</span>
</div>
</div>
<div ref="avatar" class="mt-200px w-full h-70px bg-black leading-70px">
<span class="text-white"> 头像栏 2 height:70px</span>
</div>
</div>
</div>
</template>
<style></style>
总结
挪动端和这个的实现形式大同小异,这外面还有很多相似的办法,但其实外围知识点就是 scrollTop
属性的应用。把握好这个属性的应用办法,能够让你在判断用户滚动到某些高度的时候做的交互更加得心应手。
如果你对 offsetWidth
,scrollWidth
和 cilentWidth
这几个属性不太理解,那么我强烈建议你看看上面这篇文章,带你深入浅出理解这几个高度的概念,他们对应的 height
属性你也自然而然能够推导出,会让你在 挪动端 的开发中思路异样清晰。
🫱 你必须晓得的 clientWidth, offsetWidth, scrollWidth.🎁
最近在实现一个 window
的全套 UI
,代码开源到了 github
。我会在之后始终更新相似的内容,包含拖拽的实现。
** 如果感觉本文对你有帮忙,无妨点个赞~
赠人玫瑰,手有余香🌹**