记录--巧用 overflow-scroll 实现丝滑轮播图

news2024/9/23 9:30:39

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

前言: 近期我在项目中就接到了一个完成轮播图组件的需求。最开始我也像大家一样,直接选择使用了知名的开源项目 "Swiper",但是后来发现它在移动端项目中某些测试环境下会白屏一段时间。无论如何调试都不能修复这个问题,于是就自己上手写了个轮播图组件,实现代码其实也只有 200 行,很少但是完美解决了我们项目的问题。

虽然已经 2023 年了,但是轮播图组件的实现仍然是考验前端基本功的经久不衰的题目,于是来分享一下实现思路。🎁

tips: 本文主要目的不是一上来就贴代码,而是会一步一步带你理清细节部分,即使你现在没有轮播图这个需求。

一. 使用 overflow-scroll 完成基础框架

  1. 大家在项目中肯定接触到溢出滚动的需求,其实就是用到了 overflow-auto 等相关属性。

  • 注意:样式方面,在这里我使用的是 UnoCSS ,将样式內联在了标签里,如果你还不了解这种写法,你可以点击下方的文章学习。不过即使你之前从未了解过 UnoCSS ,也不会影响你下面的阅读,因为样式不是本文的重点,并不影响整体阅读。🫱手把手教你如何创建一个代码仓库

  • 让我们快速制造一个溢出的场景来完成准备工作。其实非常简单,就是简单的创造一个容器,容器里放着三个和容器宽高相同的 div。然后给父容器一个 overflow-auto 属性,让它可以在内容溢出的时候发生滚动。

  1. 效果如下:1.gif

二. 实现合适位置自动切换

  1. 现在我们仅仅实现了一个可以滚动的容器而已,但是轮播图最主要的事情就是用户滚动的位置不合适,那么我们也要自动调整到合适的位置显示。

  2. 更具体来讲,就是当我们拖动图片到了中间这样的位置松手时,轮播图最重要一个功能就是可以自动切换到上一张或者下一张,准确的显示合适的内容给用户。(因为展示内容区域展示一半一半的内容毫无意义嘛。)image.png

  3. 这里就需要用到两个至关重要的 CSS 属性,

    • snap-type
    • snap-align

    我们先看 snap 这个单词的意思。在这里它的意思我认为 “咔嚓一声,折断” 更符合这个属性的含义,不要着急,你可以暂时先带着这个模糊的概念来慢慢理解接下来的内容。image.png

  4. 我们先看 snap-type 是用来干什么的。image.png
    这里 MDN 的解释不是特别好懂,接下来我会用人话翻译一下它想表达的含义。

  5. 回到我们的代码部分,我们创建了一个容器 div,并且这个容器因为溢出,并且设置了 overflow-滚动 相关属性。image.png
    其实我们的 scroll-type 是用来给滚动容器的!这里特别注意,它一定是用在设置了 overflow-auto 等属性的那个元素上的。

  6. 关于属性值,我们采用 snap-type: x mandatoryimage.png
    在这里 x 的含义代表着横轴发生的滚动,那么聪明的你可以猜到,它也有一个 y 属性,代表着竖轴发生滚动时的设置。

  7. 这里还有一个关键字 mandatory 代表着强制的意思。因为在某些情况下,浏览器会认为用户滑到下面这种位置是自愿的,但是我们的场景是不需要考虑这种情况的,所以要告诉浏览器我们需要你帮我 “强制咔嚓折断”image.png

  8. 至于 proximity ,这个属性的算法有点奇怪,我也没太搞懂它的含义,不过我们的需求不需要用到这个关键字,大家有兴趣也可以自行查阅。

  9. 接下来给我们的容器设置这个属性,让我们先看看效果。image.png2.gif

  10. 什么情况?怎么没效果呢?目前为止我们仅仅给容器设置了滚动的需求还是不够的,还得告诉子元素滚动到什么位置停下才行。这里就需要用到 snap-align 属性了。它是给滚动容器的子元素设置的。

  11. snap-align ,这个属性有三个值可以设置,nonecenterendimage.png
    其实从这个属性的名字就可以猜到,它其实设置的是子元素的位置是相对于滚动容器的左边对齐还是右边对齐。

  12. 怎么理解呢?我们将滚动容器的宽度调大,让它可以漏出一点点其它元素的内容。并且只给数字2的元素设置 scroll-align 相关属性。(tips: 这里需要重点注意,我们只给了一个元素设置了这个属性,另外两个元素是没有设置这个属性的。)

    • snpa-align: start (元素2无论如何都会在松开鼠标的时候紧贴着滚动容的左边,也就是滚动容器的 start 位置 start.gif

    • snap-align: center (元素2无论如何都会紧贴着滚动容器中间位置 center.gif

    • snap-align: end (元素2的右边无论如何都会紧贴着滚动容器 end.gif

  13. 知道了这三个属性的区别,那么接下来复原我们的容器样子,因为我们实际上轮播图的每一项的宽高和滚动容器的内容区是恰好相等的,所以我们给子元素无论设置怎样的三个值的效果都是一样的。image.png
    让我们看一下效果:4.gif
    看起来效果还不错~

三. 实现上一项和下一项切换功能

  1. 我们准备两个按钮,当用户点击这两个按钮的时候,可以进行手动的切换上一张和下一张。image.png

  2. 这里我们需要用到滚动容器的 scroll 事件,需要给滚动容器绑定相对的回调函数。image.png
    这里通过 e.target 就可以拿到我们滚动容器本身。容器自身存在一个 scollLeft 属性,你需要知道一个知识点其实发生滚动的本质就是 scrollLeft 值的变化image.png
    注意观看下面滚动容器的 scrollLeft 属性值的变化。scroll.gif

  3. 知道了这个关键点,那么我们的 prenext 函数就可以很明确的书写了。 首先通过 ref 拿到元素本身。image.png

  4. 然后在 pre 函数内部获取当前滚动元素的 scollLeft 值。image.png

  5. 紧接着,你需要知道的是,这个值即是一个可读属性,也是一个可写属性。那么我们就可以进行判断,如果当前照片不是第一张的话。,那么我就让 scrollLeft 的值 -300。这里有两个关键的知识点。

      1. 第一张对应的 scrollLeft 等于0
      1. 这里的 300 是我们写死的宽度,你可以根据后面自己的项目优化这个值。

    image.png

  6. 让我们看一下效果,先让我们手动滚动到第三张,然后点击上一张切换。5.gif

  7. 这里好像有一点点不对劲,我们不是平缓过度到上一张的而是直接切换到上一张的,这里很简单,需要给滚动容器设置一个 scroll-behavior:smooth 即可。image.png
    我们看一下效果:6.gif

  8. 下一张按钮的实现同理,这里不过多赘述,代码如下:image.png

  9. 最终的效果:7.gif

四. 源码

<script setup lang="ts">
import { ref, computed } from "vue";


const box = [
  {
    number: 1,
    bg: "blue",
  },

  {
    number: 2,
    bg: "pink",
  },

  {
    number: 3,
    bg: "red",
  },
];

const containerEl = ref<HTMLDivElement>();

function scrollEvent(e: UIEvent) {
  const containerEl = e.target as HTMLDivElement;
}

// 上一张
function pre() {
  const el = containerEl.value;
  if (!el) return;

  const scrollLeft = el?.scrollLeft;

  if (scrollLeft > 0) {
    el.scrollLeft = scrollLeft - 300;
  }
}

function next() {
  const el = containerEl.value;
  if (!el) return;

  const scrollLeft = el?.scrollLeft;

  const max = (box.length - 1) * 300; //轮播图的数量 -1

  if (scrollLeft < max) {
    el.scrollLeft = scrollLeft + 300;
  }
}
</script>

<template>
  <div
    class="w-100vw h-100vh text-14px text-black flex justify-center items-center"
  >
    <div
      @click.stop="pre"
      class="w-60px h-60px rounded-full bg-black flex items-center justify-center"
    >
      <span class="text-white">上一张</span>
    </div>

    <div
      ref="containerEl"
      @scroll="scrollEvent"
      class="w-300px h-300px overflow-auto flex snap-x snap-mandatory scroll-smooth"
    >
      <div
        v-for="(item, index) in box"
        class="w-300px h-300px shrink-0 leading-300px text-center snap-center"
        :style="{ backgroundColor: item.bg }"
      >
        <span class="text-100px text-white">{{ item.number }}</span>
      </div>
    </div>

    <div
      @click="next"
      class="w-60px h-60px rounded-full bg-black flex items-center justify-center"
    >
      <span class="text-white">下一张</span>
    </div>
  </div>
</template>

本文转载于:

https://juejin.cn/post/7248655627927601207

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

 

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

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

相关文章

Go的性能优化建议

前言&#xff1a; \textcolor{Green}{前言&#xff1a;} 前言&#xff1a; &#x1f49e;这个专栏就专门来记录一下寒假参加的第五期字节跳动训练营 &#x1f49e;从这个专栏里面可以迅速获得Go的知识 Go的性能优化建议 3 性能优化建议3.1 性能优化建议 - Benchmark3.2 性能优化…

一文解答危废行业信息化平台的必要性——哲讯智能科技

危险废物物联网监管系统可以通过物联网技术实现对危险废物的精准管理&#xff0c;不仅有利于提高危险废物管理水平&#xff0c;而且能够有效防范和减少重特大事故的发生&#xff0c;保障人民群众生命财产安全。利用物联网技术&#xff0c;通过传感器、无线网络、移动终端等设备…

linux CentOS 7下载步骤

1、官网地址&#xff1a;https://www.centos.org/download/ 2、 3、下载阿里云 4、下载 或minimal - 2009

08-购物车效果

先做数据&#xff0c;再做功能&#xff0c;最后界面 var goods [{pic: ./assets/g1.png,title: 椰云拿铁,desc: 1人份【年度重磅&#xff0c;一口吞云】√原创椰云topping&#xff0c;绵密轻盈到飞起&#xff01;原创瑞幸椰云™工艺&#xff0c;使用椰浆代替常规奶盖打造丰盈…

【SAS】【01】【scsi协议族】SCSI standards family

下图显示了SAM协议与SCSI协议族中其他协议标准和相关项目的关系。 SCSI Architecture Model: 定义SCSI系统模型、SCSI标准集的功能划分以及适用于所有SCSI实现和要求。Device-Type Specific Command Sets: 定义特定设备类型的实现标准&#xff0c;包括每种设备类型的设备模型。…

leetcode1884. 鸡蛋掉落-两枚鸡蛋.动态规划-java

鸡蛋掉落-两枚鸡蛋 leetcode1884. 鸡蛋掉落-两枚鸡蛋题目描述解题思路代码演示 动态规划代码演示 动态规划专题 leetcode1884. 鸡蛋掉落-两枚鸡蛋 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/egg-drop-with-2-eggs-a…

基于Python和Spacy的命名实体识别

命名实体识别&#xff08;Named Entity Recognition&#xff0c;简称NER&#xff09;是一种自然语言处理&#xff08;NLP&#xff09;方法&#xff0c;用于检测和分类文本中的命名实体&#xff0c;包括人物、组织、地点、日期、数量和其他可识别的现实世界实体。 Spacy是一个基…

STM32之HAL库微妙延迟(借助Systick)

代码 void bsp_us_delay(uint32_t us) {uint32_t start, now, delta, reload, us_tick;start SysTick->VAL;reload SysTick->LOAD;us_tick SystemCoreClock / 1000000UL;do {now SysTick->VAL;delta start > now ? start - now : reload start - now;} whi…

Element el-dropdown 事件

我这里是结合el-table一起使用 设置trigger"click" 就可以加点击事件 这里我需要点击下拉选择值后&#xff0c;既要得到下拉里面的值 也要得到这一行数据的值 重要的代码 <el-dropdowntrigger"click"command"handleCommand($event,scope.row,sc…

7 拓展中断_事件控制器(EXTI)

目录 EXTI-扩展中断和事件控制器 事件的概念 EXTI-扩展中断和事件控制器 EXTI外设框图 F1/F4/F7&#xff08;看懂与或门&#xff09; H7 STM32CubeMX中的EXTI配置 EXTI-扩展中断和事件控制器 事件的概念 STM32上许许多多的外设&#xff0c;是通过内部信号来协同工作的。…

VMware麒麟Kylin系统安装Linux

麒麟系统常用链接 https://www.jianshu.com/p/f58e2435b650 ios下载链接 https://eco.kylinos.cn/partners/mirror.html 其实基本上只有两个区别&#xff0c;一个是桌面操作系统和服务器操作系统的区别&#xff0c;一个是x86_64和arm内核的区别&#xff0c;我下的是这个海光版…

Splashtop 荣获2023年教育科技突破奖

2023年6月8日 加利福尼亚州库比蒂诺 Splashtop 在简化随处办公远程解决方案领域处于领先地位&#xff0c;该公司自豪地宣布其在教育科技突破奖评选活动中荣获“年度远程学习解决方案供应商奖”。这项在教育行业久负盛名的奖项特别关注创新性解决方案和创意公司&#xff0c;这些…

BlendOS 3 正在开发:承诺支持九个 Linux 发行版,无存储库更新

导读blendOS 发行版承诺混合 Arch Linux、Fedora Linux 和 Ubuntu&#xff0c;今年 4 月发布的 blendOS 2 使用 WayDroid&#xff0c;承诺运行 Android 应用程序。 开发商 Rudra Saraswat 表示&#xff0c;不可变发行版 blendOS 3 系统正在开发中&#xff0c;并承诺为不可变发行…

Nginx优化及防盗链

目录 一、隐藏版本号 1.查看版本号 2.修改配置文件 3.重启服务及查看版本号 二、修改用户 与组 1.修改配置文件 2.重启服务 三、缓存时间 1.修改配置文件 2.重启服务 3.测试访问 四、日志分割 1.写脚本 2.赋予执行权限并执行 3.验证 4.设置定时任务 五、连接超时 2…

ctfshow文件包含web87-117

1.web87 绕过死亡待可以使用rot13编码,还可以用base64编码,url两次编码&#xff0c;浏览器自动进行解码一次&#xff0c;代码解码一次&#xff0c;如果之编码一次&#xff0c;代码会被浏览器解码一次&#xff0c;这时候特殊字符还是url编码&#xff0c;而如php字符串则被还原&a…

扩增子高通量测序

扩增子测序是指利用合适的通用引物扩增环境中微生物的16S rDNA/18S rDNA /ITS高变区或功能基因&#xff0c;通过高通量测序技术检测PCR产物的序列变异和丰度信息&#xff0c;分析该环境下的微生物群落的多样性和分布规律&#xff0c;以揭示环境样品中微生物的种类、相对丰度、进…

人工智能数据集处理——数据清理2

目录 异常值的检测与处理 一、异常值的检测 1、使用3σ准则检测异常值 定义一个基于3σ准则检测的函数&#xff0c;使用该函数检测文件中的数据&#xff0c;并返回异常值 2、使用箱形图检测异常值 根据data.xlsx文件中的数据&#xff0c;使用boxplot()方法绘制一个箱型图 …

headscale专有网络及其ACL控制

如何使用 Headscale ( Tailscale 开源版 ) 快速搭建一个私有专属的 P2P 内网穿透网络 内网穿透简述 由于国内网络环境问题, 普遍家庭用户宽带都没有分配到公网 IP(我有固定公网 IP, 嘿嘿); 这时候一般我们需要从外部访问家庭网络时就需要通过一些魔法手段, 比如 VPN、远程软…

未来的编程语言「GitHub 热点速览」

作者&#xff1a;HelloGitHub-小鱼干 又一个编程语言火了&#xff0c;不算新&#xff0c;因为它已经开发了一段时间。不过在本周 Hacker News 上风头十足&#xff0c;DreamBerd 除了有点意思的改 ; 分隔符为 !&#xff0c;之外&#xff0c;它还能让你用问号来标注一段你也不确定…

通过adb获取ANR日志

1、命令行输入&#xff1a;adb bugreport 2、等待日志下载完毕&#xff0c;解压bugreport文件 3、进入FS-->data-->anr