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

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

前言: 近期我在项目中就接到了一个完成轮播图组件的需求。最开始我也像大家一样,直接选择使用了知名的开源项目 "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.mfbz.cn/a/32836.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

函数调用的机器级表示

文章目录 1.Call和ret指令2. 如何访问栈帧里面的数据为什么栈底放在上面&#xff0c;栈顶放在下面X86中的寄存器EBP、ESP寄存器push 、pop 指令mov 指令总结如何访问栈帧 3. 如何切换栈帧函数调用时函数返回时 4. 完整的函数调用过程1. 一个函数的栈帧内包含哪些内容2. 汇编代码…

Jenkins 发送文件到远程服务器:Publish Over SSH 插件

Jenkins 发送文件到远程服务器&#xff1a;Publish Over SSH 插件 文章目录 Jenkins 发送文件到远程服务器&#xff1a;Publish Over SSH 插件一、Publish Over SSH 插件1、概述2、主要功能和特点3、插件主页4、安装 Publish Over SSH 插件5、配置远程主机 二、发送文件到远程主…

windows安装python开发工具pycharm

下载地址 PyCharm: the Python IDE for Professional Developers by JetBrains 点击下载 安装 双击exe安装等待安装完成即可 设置python环境 添加本地python环境 选择python.exe 所在路径即可&#xff0c;2.x版本和3.x版本都可&#xff0c;根据需要进行调整

【Spring】——Spring生命周期

前言 ❤️❤️❤️Spring专栏更新中&#xff0c;各位大佬觉得写得不错&#xff0c;支持一下&#xff0c;感谢了&#xff01;❤️❤️❤️ Spring_冷兮雪的博客-CSDN博客 前面我们讲完了Spring中有关Bean的读和取&#xff0c;我们还没有好好去了解了解Bean对象&#xff0c;这篇 …

基于appnium+python+夜神模拟器的自动化

目录 1、安装夜神模拟器 2、定位元素 3、开始编码 首先搭好appnium环境&#xff01;参考https://www.cnblogs.com/testlearn/p/11419797.html 1、安装夜神模拟器 下载安装夜神模拟器后&#xff0c;在cmd命令输入adb connect 127.0.0.1:62001&#xff0c;显示出设备则表示…

redis协议与异步方式学习笔记

目录 1 交互方式 pipline2 广播机制2.1 概念演示2.2 使用场景 3 redis事物3.1 概念3.2 使用场景3.3 解决的问题3.3.1 背景&#xff1a;多线程竞争出现问题3.3.2 事务3.3.3 安全性事务 3.4两种类型的“事务”3.4.1 watch ... multi exec3.4.2 lua 脚本实现“原子”执行&#xff…

再以汇编代码分析c++的右值引用

汇编分析c语言的执行结果最为准确。 可见&#xff0c;右值引用其实还是引用&#xff0c; bb 和 cc 都是对 aa 的引用&#xff0c;其内存里存储了 aa 的地址。 而且还有一个很奇特的现象&#xff0c;bb无法给cc赋值&#xff0c;右值引用无法给右值赋值。 同样是调用std:: move…

d2l_第七章学习_卷积神经网络

参考: d2l今日学习——卷积神经网络&#xff08;CNN&#xff09;https://blog.csdn.net/m0_61165991/article/details/124176077图像工程&#xff08;上册&#xff09;-图像处理傅里叶变换https://blog.csdn.net/qq_43369406/article/details/131350139CNN卷积神经网络基础知识…

STC15 Proteus仿真DHT11环境湿度采集报警系统STC15W4K32S4-0043

STC15 Proteus仿真DHT11环境湿度采集报警系统STC15W4K32S4-0043 Proteus仿真小实验&#xff1a; STM32 Proteus仿真DHT11环境湿度采集报警系统STC15W4K32S4-0043 功能&#xff1a; Protues版本&#xff1a;8.9 硬件组成&#xff1a;STC15W4K32S4单片机 LCD1602显示器DHT11…

基于深度学习的高精度推土机检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度推土机检测识别系统可用于日常生活中检测与定位推土机目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的推土机目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检测模型训…

2023 node 接入腾讯云短信服务,实现发送短信功能

1、在 腾讯云开通短信服务&#xff0c;并申请签名和正文模板 腾讯云短信 https://console.cloud.tencent.com/smsv2 a、签名即是短信的开头。例如 【腾讯云短信】xxxxxxx&#xff1b; b、正文模板即短信内容&#xff0c; 变量部分使用{1}&#xff0c; 数字从1开始累推。例如&a…

深度学习-第T10周——数据增强

深度学习-第T10周——数据增强 深度学习-第T10周——数据增强一、前言二、我的环境三、前期工作1、导入数据集2、查看图片数目 四、数据预处理1、 加载数据1.1、设置图片格式1.2、划分训练集1.3、划分验证集1.4、查看标签1.5、再次检查数据1.6、配置数据集 2、数据可视化 五、数…

软件工程实践总结

前言 这次我们学校花了很多心血在这次的课设上&#xff0c;真的是特别感动和感谢&#xff0c;当你遇到真心为你好对你好的老师的时候&#xff0c;真的是会觉得人间值得&#xff01; 之前在学软件工程的时候我就会觉得这些理论的东西有什么用啊&#xff0c;什么UML&#xff0c;…

Scrapy框架之下载中间件(详解)

目录 Scrapy中下载中间件 概念 方法 process_request(self, request, spider) 参数: process_response(self, request, response, spider) 参数 基本步骤 示例代码 注意 Scrapy 中 Downloader 设置UA 开发UserAgent下载中间件 代码 三方模块 配置模块到Settin…

【js30天挑战】第四天:数组操作

总结 filter(筛选条件为true的项) map(你想要输出的东西)&#xff0c;进来多少个 出去多少个 sort()&#xff0c;默认可排字母顺序。sort(compareFn(a, b))其中compareFn(a, b)返回的值若大于0则a在b的后面。 reduce()&#xff0c;最复杂。reduce(func(){上一轮计算出的结果…

Flink-SQL 写入PostgreSQL 问题汇总

​ 1.主键字段为空问题 错误信息 org.apache.flink.table.api.TableException: Column bus_no is NOT NULL, however, a null value is being written into it. You can set job configuration table.exec.sink.not-null-enforcerDROP to suppress this exception and drop …

罗技k380键盘教程

在智能手机和平板电脑上享受台式电脑般舒适便捷的输入体验。罗技蓝牙™ 多设备键盘 K380 是一款小巧独特的键盘&#xff0c;让您在家中任何地方都能使用个人设备进行沟通和创作。 借助便捷的易于切换™ 按钮&#xff0c;可以通过蓝牙™ 无线技术同时连接最多三台设备&#xff…

【实用技巧】使用USB数据线向亚马逊kindle导入电子书

一、内容简介 本文主要介绍如何使用USB数据线向亚马逊kindle阅读器导入电子书。 二、所需原料 笔记本电脑、Kindle阅读器、Kindle适配的USB-a数据线。 三、导入方法 1、使用USB-a数据线将Kindle阅读器与电脑连接。 2、找到Kindle文件夹-documents-Downloads-Items1目录。…

Django框架实现简单的接口开发

前提创建一个Django项目&#xff0c;目录如下&#xff1a; Django框架上进行GET请求接口开发示例: 1.在上面项目结构目录Template下&#xff0c;新建一个login.html页面&#xff0c;定义表单提交请求的方式为post&#xff0c;具体代码如下。 <!DOCTYPE HTML> <html …

freemarker 使用word模板赋值

1. 引包<dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.28</version></dependency>word文档工具类import freemarker.template.Configuration; import freemarker.template.…
最新文章