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

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

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

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

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

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

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

    手把手教你如何创建一个代码仓库

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

  1. 效果如下:

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

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

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

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

    • snap-type
    • snap-align

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

  4. 我们先看 snap-type 是用来干什么的。



    这里 MDN 的解释不是特别好懂,接下来我会用人话翻译一下它想表达的含义。

  5. 回到我们的代码部分,我们创建了一个容器 div,并且这个容器因为溢出,并且设置了 overflow-滚动 相关属性。



    其实我们的 scroll-type 是用来给滚动容器的!这里特别注意,它一定是用在设置了 overflow-auto 等属性的那个元素上的。

  6. 关于属性值,我们采用 snap-type: x mandatory



    在这里 x 的含义代表着横轴发生的滚动,那么聪明的你可以猜到,它也有一个 y 属性,代表着竖轴发生滚动时的设置。

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

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

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



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

  11. snap-align ,这个属性有三个值可以设置,nonecenterend



    其实从这个属性的名字就可以猜到,它其实设置的是子元素的位置是相对于滚动容器的左边对齐还是右边对齐。

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

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

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

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

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



    让我们看一下效果:



    看起来效果还不错~

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

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

  2. 这里我们需要用到滚动容器的 scroll 事件,需要给滚动容器绑定相对的回调函数。



    这里通过 e.target 就可以拿到我们滚动容器本身。容器自身存在一个 scollLeft 属性,你需要知道一个知识点其实发生滚动的本质就是 scrollLeft 值的变化



    注意观看下面滚动容器的 scrollLeft 属性值的变化。

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

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

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

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

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

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



    我们看一下效果:

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

  9. 最终的效果:

四. 源码

<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 实现丝滑轮播图的更多相关文章

  1. 记录一下自己用jQuery写的轮播图

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  2. [转] 设置div的overflow:scroll,但是在手机上滑动的时候有点卡顿

    设置div的overflow:scroll,但是在手机上滑动的时候有点卡顿,所以在这个div上加一个css: -webkit-overflow-scrolling : touch; 在苹果手机上使用- ...

  3. CSS中overflow:scroll怎么设置只上下滚动而不左右滚动

    CSS中"overflow:scroll"默认是左右,上下都滚动.怎么设置只上下滚动而不左右滚动,下面有个不错的解决方法 CSS中"overflow:scroll&quo ...

  4. iScroll框架解析——Android 设备页面内 div(容器,非页面)overflow:scroll; 失效解决(转)

    移动平台的活,兼容问题超多,今儿又遇到一个.客户要求在弹出层容器内显示内容,但内容条数过多,容器显示滚动条.按说是So easy,容器设死宽.高,CSS加属性 overflow:scroll; -we ...

  5. 通过overflow: scroll;来实现部分区域的滚动

    在移动端中,我们希望元素的滚动,可以通过一些插件的使用来实现滚动,当然也可以自己来实现. 比如:对于某一个区域,我们可以限制好高度之后,设定:overflow-y: scroll; 这样,就可以实现滚 ...

  6. overflow:scroll 滚动条不显示

    overflow:scroll 滚动条不显示 ::-webkit-scrollbar-thumb 可能因为 自定义的滚动条height比元素可展示内容大

  7. 解决页面使用overflow: scroll,overflow-y:hidden在iOS上滑动卡顿的问题

    解决页面使用overflow: scroll,overflow-y:hidden在iOS上滑动卡顿的问题 div{ width: 100%; overflow-y: hidden; -webkit-o ...

  8. ios下使用overflow scroll情况下,到达最极端的情况时会拖动整个页面的解决办法

    今天开发ipad webapp时,遇到个问题就是在支持内部滚动(overflow:scroll)的页面中,在滚到到最极端(最上或者最下时),会拖动整个页面,带来不好的用户体验. 方法一,从网上找到的: ...

  9. 内层元素设置position:relative后父元素overflow:hidden overflow:scroll失效 解决方法

    内层元素设置position:relative后父元素overflow:hidden overflow:scroll 都失效 解决方法:在position:relative的外层父容器加positio ...

  10. 父元素设置固定宽度并设置overflow:scroll,如何让子元素撑开父元素

    <div class="a"> <div class="b"> <div class="c">内容内容, ...

随机推荐

  1. 存储过程分页以及参数拼接sql语句、C#调用存储过程

    1.C#调用存储过程,带参数返回的功能,而且是参数化拼接,这样就可以防止sql注入 System.Data.SqlClient.SqlParameter[] parameters = { new Sy ...

  2. NodeJs web项目框架Express笔记

    安装 以下都使用Yarn进行. 环境前提: 已经安装NodeJS(及自带的npm), 已经安装Yarn # 全局安装 yarn global add express-generator@4 #查看版本 ...

  3. Oracle开发人员守则

    以下为Oracle大师级语录: Oracle Database developers should follow is to do everything they can in SQL. What t ...

  4. Oracle设置和删除不可用列

    Oracle设置和删除不可用列 1.不可用列是什么? 就是表中的1个或多个列被ALTER TABLE-SET UNUSED 语句设置为无法再被程序利用的列. 2.使用场景? If you are co ...

  5. Java常用编程类库

    Java语言已经有许多非常成熟的开源基础类库,封装了日常开发中的各种常用操作,如:对象判空,字符串编码,本地缓存等等. 可以直接在项目中引入对应类库使用即可,或者参与完善相应类库的方法. 现将常用的基 ...

  6. 【ACM专项练习#03】打印图形、栈的合法性、链表操作、dp实例

    运营商活动 题目描述 小明每天的话费是1元,运营商做活动,手机每充值K元就可以获赠1元,一开始小明充值M元,问最多可以用多少天? 注意赠送的话费也可以参与到奖励规则中 输入 输入包括多个测试实例.每个 ...

  7. 第132篇:npm第一次使用自己的包(package-lock.json、package.json文件作用说明)

    好家伙,   1.新建一个文件夹,命名为test   2.下载包 npm i panghu-planebattle   空白的文件夹中多了两个文件 package-lock.json和package. ...

  8. 【Azure ACR+App Service】ACR WebHook请求App Service时遇见 401 Unauthorized

    问题描述 App Service 支持从ACR中直接拉取镜像,并且可以配置持续部署(Continuous Deployment), 它是通过在ACR中添加一个Webhook,然后发送POST请求到 & ...

  9. C笔记(2014-12备份)

    Video1: 1-编译器对待全局变量和局部变量的差别.全局变量分配空间是在数据区,局部变量分配在代码区. (比如局部变量 int lo_var = 2;后面的 = 2;是赋值语句,被编译器转化成机器 ...

  10. Redisson 框架中的分布式锁

    实现分布式锁通常有三种方式:数据库.Redis 和 Zookeeper.我们比较常用的是通过 Redis 和 Zookeeper 实现分布式锁.Redisson 框架中封装了通过 Redis 实现的分 ...