前言: 从最开始应用掘金之后,就对掘金 PC 端和挪动端Tab 栏的实现感到好奇。本人对于页面滚动时要做出交互成果始终是我单薄的中央。然而目前公司的我的项目外围都是以挪动端为主,如果不把握一些这部分常识,就无奈做出一些令人难受的交互逻辑。遂明天特意抽时间去学习了一下相干原理,这种成果的实现思路有很多,我只解说我学习到的一种形式。


咱们先预览最终效果图:

一. 剖析需要

  1. 咱们以 PC 端为例来剖析接下来要讲的内容。
  2. 能够分明的看到,首页顶部 Tab 随着咱们的滚动开始进行自动隐藏。
  3. 这是起始状态,页面未产生滚动,顶部只存在一个 Tab
  4. 这是中间状态,在某一个时刻同时存在两个 Tab
  5. 这是最终状态,随着页面滚动到某一个临界值,最初只留下了头像 Tab

二. 筹备工作

  1. 咱们先创立一个简略的能够滚动的场景。(你也能够间接在源码题目间接复制我的代码,前提是你也在应用 UnoCSS,如果你不分明 UnoCSS 的应用办法,那你能够点击上面这篇文章。)
    手把手教你创立本人的代码仓库)
  2. 上面是咱们目前的状态,没有做任何对于滚动的响应式。
  3. 我置信大部分读者十分分明的晓得,当咱们页面产生滚动的时候,滚动的元素会触发一个 onScroll 事件,这个事件也是常常被拿来当防抖和截流的例子,然而明天咱们不思考防抖和截流,咱们先用用这个事件是如何触发的。
  4. 你须要在你设置了 overflow-auto 的元素身上绑定一个回调函数,当页面产生滚动的时候,该函数就会被正确的触发,这也是咱们本文的重点。

    能够看到,当我滚动页面的时候,这个函数正在被触发,并且触发频率十分快。

三. scrollTop

  1. 这里你要晓得,当滚动事件触发的时候,该回调函数会被传递一个事件参数。
  2. etarget 属性指的就是正在产生滚动的这个元素。
  3. 它身上有一个非常重要的属性,就是咱们明天的配角 scrollTop。咱们间接打印一下,看一下这个属性是如何变动的。
  4. 聪慧的你肯定很快就能发现,它其实就代表着咱们实际上滚动的间隔。说的更确切一点,它代表着咱们滚动元素间隔页面顶部的间隔
  5. 既然咱们曾经晓得了页面理论滚动的间隔,咱们还晓得这两个 Tab 的具体高度,那么咱们就能够在适合的机会去操作这两个元素的属性,让它随之咱们的页面来做一些响应式的变动。
  6. 咱们先给这两个 Tab 取两个名字,并且打上对于的 ref,因为接下来咱们要频繁的去操作这两个元素的款式。

四. 实现页面滚动响应式

  1. 回顾第一个状态,页面没有产生滚动,咱们的 avatar 标签是没有展现的。
  2. 咱们这里从新设计一下款式,切换咱们的 searchsticky,并且设置 top-0,使它一开始能够固定在咱们的页面顶部。而后再加一点点和 avatar 的间距,待会咱们马上就要通过滚动实现一些成果。

    绝对应的页面成果如下:
  3. 这里其实咱们要用到一个障眼法,咱们须要给 search 栏设置一个兄弟元素,并且这个兄弟元素的属性恰好和咱们的 avatar 栏是截然不同的。(指的是款式和性能一样)所以你当初的页面应该是上面这个样子。
  4. 首先明确的要晓得,头像栏1 在最开始的没滚动到一临界值的时候是不会展现进去的。这里咱们之间给它设置一个 opacity-0,让它的透明度是0。
  5. 接下来干的事件就非常简单了,咱们这里再看一下掘金的成果。

    这里咱们看到,在同一时间会同时存在两个框框,那么咱们滚动的最小值即可算进去。

    依据上图咱们能够晓得,当咱们滚动 200px(margin-top)+ 70px 的时候,恰好 search头像栏的顶部接触。
  6. 那么此时咱们不做任何限度,持续往下滚动头像栏2 的高度70px。那么页面此时恰好会把头像栏2遮挡住对吧?为了不便展现,我把 scrollTop 的值贴上去了。(这里有些许误差,是我滚轮并不是特地容易滚动到那个数值。)

五. 实现顶部过渡切换

  1. 这里咱们须要加一个变量 isShow,并且咱们把头像栏2的透明度款式设置:style 的模式使之能够动静的切换。


    此时的页面成果应该是这样:
  2. 能够看到当咱们页面滚动到齐全看不到头像栏2的时候,咱们只须要让头像栏1的透明度变为1即可实现相似于坑骗用户眼睛的感觉,如同头像栏2又贴着回来了。
  3. 此时还差最初的一步,search 栏上移,只展现头像栏1

  4. 那么接下来要做的事件十分非常简单,就是让搜寻栏在此时往上挪动本身高度即可。

    成果如下:
  5. 嗯...成果有些许僵硬,咱们加一个简略的过渡,让 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 属性的应用。把握好这个属性的应用办法,能够让你在判断用户滚动到某些高度的时候做的交互更加得心应手。
如果你对 offsetWidthscrollWidthcilentWidth 这几个属性不太理解,那么我强烈建议你看看上面这篇文章,带你深入浅出理解这几个高度的概念,他们对应的 height 属性你也自然而然能够推导出,会让你在挪动端的开发中思路异样清晰。

你必须晓得的 clientWidth, offsetWidth, scrollWidth.

最近在实现一个 window 的全套 UI ,代码开源到了 github。我会在之后始终更新相似的内容,包含拖拽的实现。

**如果感觉本文对你有帮忙,无妨点个赞~
赠人玫瑰,手有余香**