不可思议,纯 css 都能图片滚动

背景

传统的swiper太重了,里面封装了很多我们不需要的功能,而一个简单的滚动功能没必要那么重的文件。于是就想着自己如何实现,如何才能用最少的代码最优雅的实现呢?是否可以推翻传统的实现,使用纯css的某些特效实现呢?

肯定可以的呀,我就实现了一个基于scroll-snap-type属性做的滚动

实现思路

scroll-snap-type:网页容器滚动停止的时候,自动平滑定位到指定元素的指定位置,有点像当子元素滚动到某一个点的时候会被父元素吸附过去,它的目的是让你的页面滚动停留在你希望用户关注的重点区域,利用这个css属性,就可以自动判断用户是要滚到哪

那么问题又来了,这个临界点我们怎么设置呢?css 属性都是相辅相成的,我们可以使用scroll-snap-align:发生滚动的时候,在一屏内对齐方式,scroll-snap-type 会根据 scroll-snap-align的设置的临界点进行滚动,如果不设置它没有任何效果

图片

scroll-snap-align有几个参数,start,center,end,分别感受一下他们之间的区别

scroll-snap-align:start

scroll-snap-align:center

scroll-snap-align:end·

平滑定位到指定元素的指定位置的效果实现了;滚动最关键最重要的一步,就是如何让元素平滑缓慢的滚动呢?这时候scroll-behavior派上用场了,它的目的是滚动的时候自带动效一点都不生硬,作为用户的我体验极好

没有用的时候

使用了之后

对比效果还是很明显的

把上面提到的三个属性放在一起就实现了平稳缓慢的滚动,再借助js移动位置我们的自动轮播滚动就完美的实现了。

// css
.swiper-box {
  scroll-behavior: smooth;
  scroll-snap-type: x mandatory;
}
.swiper-image {
  scroll-snap-align: start;
}
// js
setInterval(function () {
   var clientWidth = ele.clientWidth;
   var index = Math.floor(ele.scrollLeft / clientWidth) + 1;
   if (index > imageList.length - 1) {
     index = 0;
   }
   eleSwiperBox.scrollLeft = clientWidth * index + _ele.offsetLeft * index;
}, 3000)
复制代码

就是这么简单,几行代码就实现了滚动自动轮播。如上面所说用最少的代码最优雅 就这样高高兴兴的结束了么?别急,投入项目使用要再看看浏览器的兼容性的,如果兼容性不好的话,很有可能就没法投入到项目中去

图片

Safari浏览器都不支持,完了完了,不支持就相当于没有,可以是又想用,那就只能写一个 polyfill

我们想想scroll-behavior: smooth; 实现的效果是怎么样的?

图片

是滚动的过程中缓慢的滚,有条不紊,按照一定的步长再动,好像在做移动匀速的直线运动

知道了原理就好办了在属性不支持的情况下我们就写一个递归函数,ele.scrollLeft不是一步到位,而是慢慢的每次只滚动一点点,一直到结束。

  if (!CSS.supports("scroll-behavior: smooth")) {
     var step = function () {
       var numScrolDistance = scrollLeft - ele.scrollLeft;
       if (Math.abs(numScrolDistance) <= 3) {
         ele.scrollLeft = scrollLeft;
       } else {
        ele.scrollLeft += numScrolDistance / 4;
         requestAnimationFrame(step);
       }
     };
     step();
   } else {
     ele.scrollLeft = scrollLeft;
   }
复制代码

用js写了一个ployfill,我们的兼容性问题就解决了。组合css的几个属性我们的自动轮播滚动效果就实现了,代码很简单,主要是可以使用尝试新的用不一样css解决方案。

不仅仅只有轮播滚动

如果我们不做轮播滚动,做点击缓慢滚动也是很方便很好使用的属性。

像这种情况也是很好使用的。之前在项目中就遇见过这种需求,实现了效果比较生硬,代码也不优雅,后来有了css大佬坐镇指点,用的css属性结合递归的实现,特别有意思

代码封装一下

把上面的代码稍微封装一下,写成一个组件,在我们的在项目中就可以随意使用了,一次封装终身享用。都是原生的实现,没有框架的限制,有兼容性的处理。 还附带了图片懒加载和异常处理

代码封装

  1. 可以npm安装使用

npm i snap-swiper

import "snap-swiper/snap-swiper.css";
const snapSwiper = require("snap-swiper");
snapSwiper({
    imageList:[],
    el,
 });

最后,想学习前端的小伙伴们!

如果还在IT编程的世界里迷茫,不知道自己的未来规划,学习没有动力,东也学一下,西也学习一下,那你可以加入web前端学习交流Q群:733581373, 里面有大神一起交流并走出迷茫。新手可进群免费领取学习资料,分享一些学习的方法和需要注意的小细节,每晚八点也会准时的讲一些前端的小案例项目。

作者:阅文前端团队
链接:https://juejin.im/post/6895584191073927175
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值