记录--巧用 overflow-scroll 实现丝滑轮播图
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
前言: 近期我在项目中就接到了一个完成轮播图组件的需求。最开始我也像大家一样,直接选择使用了知名的开源项目 "Swiper",但是后来发现它在移动端项目中某些测试环境下会白屏一段时间。无论如何调试都不能修复这个问题,于是就自己上手写了个轮播图组件,实现代码其实也只有 200 行,很少但是完美解决了我们项目的问题。
虽然已经 2023 年了,但是轮播图组件的实现仍然是考验前端基本功的经久不衰的题目,于是来分享一下实现思路。
tips: 本文主要目的不是一上来就贴代码,而是会一步一步带你理清细节部分,即使你现在没有轮播图这个需求。
一. 使用 overflow-scroll 完成基础框架
大家在项目中肯定接触到溢出滚动的需求,其实就是用到了 overflow-auto 等相关属性。

注意:样式方面,在这里我使用的是
UnoCSS,将样式內联在了标签里,如果你还不了解这种写法,你可以点击下方的文章学习。不过即使你之前从未了解过UnoCSS,也不会影响你下面的阅读,因为样式不是本文的重点,并不影响整体阅读。
手把手教你如何创建一个代码仓库让我们快速制造一个溢出的场景来完成准备工作。其实非常简单,就是简单的创造一个容器,容器里放着三个和容器宽高相同的 div。然后给父容器一个 overflow-auto 属性,让它可以在内容溢出的时候发生滚动。

效果如下:
二. 实现合适位置自动切换
现在我们仅仅实现了一个可以滚动的容器而已,但是轮播图最主要的事情就是用户滚动的位置不合适,那么我们也要自动调整到合适的位置显示。
更具体来讲,就是当我们拖动图片到了中间这样的位置松手时,轮播图最重要一个功能就是可以自动切换到上一张或者下一张,准确的显示合适的内容给用户。(因为展示内容区域展示一半一半的内容毫无意义嘛。)
这里就需要用到两个至关重要的 CSS 属性,
- snap-type
- snap-align
我们先看 snap 这个单词的意思。在这里它的意思我认为 “咔嚓一声,折断” 更符合这个属性的含义,不要着急,你可以暂时先带着这个模糊的概念来慢慢理解接下来的内容。
我们先看 snap-type 是用来干什么的。
这里 MDN 的解释不是特别好懂,接下来我会用人话翻译一下它想表达的含义。回到我们的代码部分,我们创建了一个容器 div,并且这个容器因为溢出,并且设置了 overflow-滚动 相关属性。
其实我们的 scroll-type 是用来给滚动容器的!这里特别注意,它一定是用在设置了 overflow-auto 等属性的那个元素上的。关于属性值,我们采用 snap-type: x mandatory。
在这里x的含义代表着横轴发生的滚动,那么聪明的你可以猜到,它也有一个y属性,代表着竖轴发生滚动时的设置。这里还有一个关键字
mandatory代表着强制的意思。因为在某些情况下,浏览器会认为用户滑到下面这种位置是自愿的,但是我们的场景是不需要考虑这种情况的,所以要告诉浏览器我们需要你帮我 “强制咔嚓折断”。
至于 proximity ,这个属性的算法有点奇怪,我也没太搞懂它的含义,不过我们的需求不需要用到这个关键字,大家有兴趣也可以自行查阅。
接下来给我们的容器设置这个属性,让我们先看看效果。
什么情况?怎么没效果呢?目前为止我们仅仅给容器设置了滚动的需求还是不够的,还得告诉子元素滚动到什么位置停下才行。这里就需要用到
snap-align属性了。它是给滚动容器的子元素设置的。snap-align,这个属性有三个值可以设置,none,center和end。
其实从这个属性的名字就可以猜到,它其实设置的是子元素的位置是相对于滚动容器的左边对齐还是右边对齐。怎么理解呢?我们将滚动容器的宽度调大,让它可以漏出一点点其它元素的内容。并且只给数字2的元素设置 scroll-align 相关属性。(tips: 这里需要重点注意,我们只给了一个元素设置了这个属性,另外两个元素是没有设置这个属性的。)
snpa-align: start (元素2无论如何都会在松开鼠标的时候紧贴着滚动容的左边,也就是滚动容器的 start 位置
snap-align: center (元素2无论如何都会紧贴着滚动容器中间位置
snap-align: end (元素2的右边无论如何都会紧贴着滚动容器
知道了这三个属性的区别,那么接下来复原我们的容器样子,因为我们实际上轮播图的每一项的宽高和滚动容器的内容区是恰好相等的,所以我们给子元素无论设置怎样的三个值的效果都是一样的。
让我们看一下效果:
看起来效果还不错~
三. 实现上一项和下一项切换功能
我们准备两个按钮,当用户点击这两个按钮的时候,可以进行手动的切换上一张和下一张。
这里我们需要用到滚动容器的 scroll 事件,需要给滚动容器绑定相对的回调函数。
这里通过e.target就可以拿到我们滚动容器本身。容器自身存在一个 scollLeft 属性,你需要知道一个知识点其实发生滚动的本质就是 scrollLeft 值的变化。
注意观看下面滚动容器的 scrollLeft 属性值的变化。
知道了这个关键点,那么我们的
pre和next函数就可以很明确的书写了。
首先通过 ref 拿到元素本身。
然后在
pre函数内部获取当前滚动元素的scollLeft值。
紧接着,你需要知道的是,这个值即是一个可读属性,也是一个可写属性。那么我们就可以进行判断,如果当前照片不是第一张的话。,那么我就让 scrollLeft 的值 -300。这里有两个关键的知识点。
- 第一张对应的 scrollLeft 等于0
- 这里的 300 是我们写死的宽度,你可以根据后面自己的项目优化这个值。
让我们看一下效果,先让我们手动滚动到第三张,然后点击上一张切换。
这里好像有一点点不对劲,我们不是平缓过度到上一张的而是直接切换到上一张的,这里很简单,需要给滚动容器设置一个
scroll-behavior:smooth即可。
我们看一下效果:
下一张按钮的实现同理,这里不过多赘述,代码如下:
最终的效果:
四. 源码
<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
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

记录--巧用 overflow-scroll 实现丝滑轮播图的更多相关文章
- 记录一下自己用jQuery写的轮播图
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- [转] 设置div的overflow:scroll,但是在手机上滑动的时候有点卡顿
设置div的overflow:scroll,但是在手机上滑动的时候有点卡顿,所以在这个div上加一个css: -webkit-overflow-scrolling : touch; 在苹果手机上使用- ...
- CSS中overflow:scroll怎么设置只上下滚动而不左右滚动
CSS中"overflow:scroll"默认是左右,上下都滚动.怎么设置只上下滚动而不左右滚动,下面有个不错的解决方法 CSS中"overflow:scroll&quo ...
- iScroll框架解析——Android 设备页面内 div(容器,非页面)overflow:scroll; 失效解决(转)
移动平台的活,兼容问题超多,今儿又遇到一个.客户要求在弹出层容器内显示内容,但内容条数过多,容器显示滚动条.按说是So easy,容器设死宽.高,CSS加属性 overflow:scroll; -we ...
- 通过overflow: scroll;来实现部分区域的滚动
在移动端中,我们希望元素的滚动,可以通过一些插件的使用来实现滚动,当然也可以自己来实现. 比如:对于某一个区域,我们可以限制好高度之后,设定:overflow-y: scroll; 这样,就可以实现滚 ...
- overflow:scroll 滚动条不显示
overflow:scroll 滚动条不显示 ::-webkit-scrollbar-thumb 可能因为 自定义的滚动条height比元素可展示内容大
- 解决页面使用overflow: scroll,overflow-y:hidden在iOS上滑动卡顿的问题
解决页面使用overflow: scroll,overflow-y:hidden在iOS上滑动卡顿的问题 div{ width: 100%; overflow-y: hidden; -webkit-o ...
- ios下使用overflow scroll情况下,到达最极端的情况时会拖动整个页面的解决办法
今天开发ipad webapp时,遇到个问题就是在支持内部滚动(overflow:scroll)的页面中,在滚到到最极端(最上或者最下时),会拖动整个页面,带来不好的用户体验. 方法一,从网上找到的: ...
- 内层元素设置position:relative后父元素overflow:hidden overflow:scroll失效 解决方法
内层元素设置position:relative后父元素overflow:hidden overflow:scroll 都失效 解决方法:在position:relative的外层父容器加positio ...
- 父元素设置固定宽度并设置overflow:scroll,如何让子元素撑开父元素
<div class="a"> <div class="b"> <div class="c">内容内容, ...
随机推荐
- NC52867 Highway
题目链接 题目 题目描述 In ICPCCamp there were n towns conveniently numbered with \(1, 2, \dots, n\) connected ...
- 最好的PDF文本编辑开发库
PDF文件是一种常见的文档格式,它具有跨平台.保持原样.安全性高等特点.但是,PDF文件也有一个缺点,就是不可编辑.如果我们想要修改PDF文件中的内容,比如文字.图片.表格等,就会很麻烦,需要转档为W ...
- 【OpenGL ES】第一个案例
1 前言 OpenGL(Open Graphics Library)是由 SGI 公司开发的一套 3D 图形软件接口标准,由于具有体系结构简单合理.使用方便.与操作平台无关等优点,OpenGL 迅 ...
- Java集合框架学习(十三) Collections类详解
Collections类介绍 这个类操作或返回集合的专有静态方法. 它包含多态算法,利用wrappers(封装器)返回指定集合类型的新集合,以及其他一些零散功能. 如果该类的方法引用的集合或类对象为n ...
- win32 - 虚拟内存的一些介绍
对32位Windows来说,其虚拟地址空间总数就是2的32次方,即4GB. 如果没有在引导时加上/3GB或/BOOTVA选项,Windows默认最大会分2GB给内核模式程序使用,2GB给用户模式程序. ...
- Golang Web 框架 Gin 基础学习教程集合目录
Gin Web 框架基础学习系列目录 01-quickstart 02-parameter 03-route 04-middleware 05-log 06-logrus 07-bind 08-val ...
- Unity学习笔记--数据持久化XML文件(1)
XML相关 Xml是可拓展标记语言,一种文件格式.我们使用xml来完成对数据持久化的存储.等待我们有一程序运行结束之后,将内存中的数据进行保存,(保存在硬盘/服务器)实现对数据的持久化存储. xml文 ...
- Mybatis-Plus自动生成代码的CodeGenerator代码
官方地址:Mybatis-Plus:https://mp.baomidou.com/guide/generator.html pom中导入mybatis plus的jar包,因为后面会涉及到代码生成, ...
- easyexcel: The maximum length of cell contents (text) is 32,767 characters
easyexcel The maximum length of cell contents (text) is 32,767 characters 使用easyexcel向excel中写内容出现了单元 ...
- 项目实战:Qt监测操作系统cpu温度v1.1.0(支持windows、linux、国产麒麟系统)
需求 使用Qt软件开发一个检测cpu温度的功能. 兼容windows.linux,国产麒麟系统(同为linux) Demo windows上运行(需要管理员权限): 国产麒麟操作上运 ...
