已经2023年了,你还不会手撕轮播图?

news2024/9/19 19:16:04

jd.gif

目录

    • 一、前言
    • 二、动画基础
      • 1. 定时器
      • 2. left与offsetLeft
      • 3. 封装函数
        • 3.1 物体
        • 3.2 目标点
        • 3.3 回调函数
      • 4.封装
    • 三、基础结构
      • 3.1 焦点图
      • 3.2 按钮
      • 3.3 小圆点
      • 3.4 总结
    • 四、按钮显示
    • 五、圆点
      • 5.1 生成
      • 5.2 属性
      • 5.3 移动
    • 六、按钮
      • 6.1 准备
      • 6.2 出错
        • 6.2.1 小圆点跟随
        • 6.2.2 图片返回
      • 6.3 bug
    • 七、定时器
    • 八、总结


一、前言

目前,在移动端或是网页端对于轮播图的需求并不可少,我们有许多代替好的框架或者组件实现这个功能,但不如我们今天自己着手定制一个原生js轮播图,顺便总结提高一下相关知识点。

轮播图目前出现在各大购物网站的首页用来展示商品信息,现在也出了很多插件帮助我们更加便捷的实现多种多样的轮播图

京东

jd.gif

天猫

tm.webp

淘宝

tb.webp

纯手写轮播图对于初学者可能很难,也会有公司面试出轮播图来考察面试者的基础能力了。其实轮播图只要细分成几个小的模块逐步实现起来还是比较简单的。

下面,带大家来实现一下简易的轮播图

二、动画基础

我们都知道轮播图是有一个动画过程的,那如何封装实现这一个动画函数呢?

1. 定时器

前端的定时器有两种,一种是一次性定时器setTimeout,一种是重复性定时器setInterval

1-定时器.gif

如上图所示,setTimeout你只有点击一下按钮物体才会向前跑过了15ms就向前跑10px。而对于setInterval只需要点击一次便会每间隔15ms执行一次,页面中的倒计时效果也是这样做的。

所以,我们的轮播图肯定要选择setInterval第二种方案了。

2. left与offsetLeft

left就是我们加了定位的物体距离左侧的位置,这里可以参考一些常见的定位属性。

offsetLeft是一个只读属性(不能修改值),返回当前元素相对于 offsetParent 节点左边界的偏移像素值。当前父亲节点是整个页面,所以只需要把offsetLeft赋值给objectleft偏移量就行了。

3. 封装函数

有了定时器之后,我们就要考虑把这段代码封装成动画函数,想要的时候调用就行了。

封装函数要注意参数问题,那么我们定时器要传进来什么参数呢?

物体 目标点 回调函数

3.1 物体

物体为我们要移动的dom元素,就是上面哪个在屏幕行动的粉色盒子。

3.2 目标点

上面的盒子运动方向是有了,但是它一旦执行起来一个劲的向前冲,这也不行呀!

所以,我们试着修改一下上面的代码,比如让它到达800px就清楚定时器让它停下来,否则继续向前运动。
这时候我们只需要在定时器加了一个if else判断就行了。

if(object.offsetLeft==500){
    clearInterval(timer);
}
else{
    object.style.left=object.offsetLeft+10+'px';
}

2-target.gif

目标点满足了,但是还有两个疑问?

  • 到达800px后,如何后退?
  • 如何改变物体的运动曲线?

这两个问题只需要一个解决方案,只需要加一个step的变量,代表每一次移动的值代替固定的10px

这个变量只需要改成下面的公式计算就行:

var step = (target - obj.offsetLeft) / 10;

我们一开始的运动曲线是这样的,匀速状态:

liner.png

通过这样的公式既可以保证物体可以后退,又满足了先加速后减速的曲线运动

easeinout.png

这个公式如果仔细查看css的距离其实会有偏差的,比实际的目标点偏小,由于浮点数的计算问题,所以要使用公式,做近似处理。

step = step > 0 ? Math.ceil(step) : Math.floor(step);

3.3 回调函数

回调函数顾名思义当我调用这个定时器函数时,到达目标点了,定时器被清空了,就可以执行我传入的回调函数了。

下面让到达800px的物体,进行变色效果。

3-callback.gif

当然,后面也可以根据自己的要求实现特点的效果。

4.封装

我们把上面写好的代码统一到一个animate.js的文件中,需要的时候引入就行了。

function animate(obj, target, callback) {
    //排他原理
    clearInterval(obj.timer);
    obj.timer = setInterval(function () {
        //步长
        var step = (target - obj.offsetLeft) / 10;
        step = step > 0 ? Math.ceil(step) : Math.floor(step);
        if (obj.offsetLeft == target) {
            clearInterval(obj.timer);
            //回调函数
            callback && callback();
        }
        else {
            obj.style.left = obj.offsetLeft + step + 'px';
        }
    }, 15);
}

为了优化代码,防止用户过度点击,我们要在定时器执行的一开始通过排他原理预先清空之前的定时器,然后再执行我们自己的定时器。

三、基础结构

1.png

搭建html页面的结构其实很简单,我们主要把它分成三个部分,分别是中间的焦点图、左右两侧的按钮、底部的小圆点

3.1 焦点图

2.png

<ul class="rotate-middle">
    <li><a href="#"><img src="images/1.jpg" alt=""></a></li>
    <li><a href="#"><img src="images/2.jpg" alt=""></a></li>
    <li><a href="#"><img src="images/3.jpg" alt=""></a></li>
    <li><a href="#"><img src="images/4.jpg" alt=""></a></li>
    <li><a href="#"><img src="images/5.jpg" alt=""></a></li>
</ul>

焦点图在底部先定义一个400*300的盒子,盒子里面放入一张张的图片。这时候要注意每一个li加上浮动ul盒子的大小也需要伸长到足够容纳这一行排列图片的大小。

3.2 按钮

<button class="btn-lt">&lt;</button>
<button class="btn-rt">&gt;</button>

按钮我没采用字体图标伪元素之类的,直接粗暴的使用普通的< >了,样式就合适的更改就行了。

按钮额外要注意添加z-index提高位置,防止被图片压住了。

3.3 小圆点

<ol class="rotate-bottom">
    <li class="current"></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
</ol>

底部小圆点现在我是直接在html里面写了,但是后面在js代码中会根据实际的图片数量实时更新。

3.4 总结

这三个基础的结构统一采用position定位(子绝父相),并且对于我们的ul也要加一个position: absolute;,因为后面要对这个盒子进行动画移动。

四、按钮显示

这部分我们的要求就是,让鼠标移动到图片的时候,按钮显示,离开不显示。正式写代码之前我们先来弄清楚一个问题?

  • mouseentermouseover有什么区别?

推荐文章:mouseenter与mouseover为何这般纠缠不清?

看完之后,选择mouseenter避免冒泡,获取时间源后,直接添加程序执行,按钮的隐藏还是显示直接使用display

focus.addEventListener('mouseenter', function () {
        lt.style.display = 'block';
        rt.style.display = 'block';
    });
    focus.addEventListener('mouseleave', function () {
        lt.style.display = 'none';
        rt.style.display = 'none';
    });

五、圆点

5.1 生成

for (var i = 0; i < ul.children.length; i++) {
    //创建ol li
    var cloneli = this.document.createElement('li');
    ol.appendChild(cloneli);
}

3.png

一开始,我们在html没给圆点,后面在js代码中根据图片的数量生成li

5.2 属性

 //自定义属性
 ol.children[i].setAttribute('index', i);

为了后面更好的移动轮播图,我们需要给每一个ol li定义一个属性index,这里我们是5张图片,index范围就是0~4

5.3 移动

//绑定事件
ol.children[i].addEventListener('click', function () {
// 排他原理
    for (var j = 0; j < ol.children.length; j++) {
        ol.children[j].className = '';
    }
    this.className = 'current';

    index = this.getAttribute('index');
    num = index;
    circle = index;
    animate(ul, -fixWidth * index);
})

4-move.gif

这时候,我们每点击一个圆点就获取它当前的index的值,然后调用动画函数传入目标值 ul 距离- 盒子的大小 * inddex,就可以移动图片了。

六、按钮

6.1 准备

左右两侧按钮移动本质上是一致的,我们先来做右侧按钮。预期目标是我每点击一次右侧按钮,图片就会向后移动一张。

那么这里我们还需要给每个图片也加上自定义属性吗?

其实不用,自定义一个变量num,随着点击的次数++就行了。

6.2 出错

5-btn.gif

如上面的图片一样,有几个问题:

  • 图片是动了,但是小圆点没动?
  • 到了最后一张图片,怎么返回?

下面,我们一个个解决。

6.2.1 小圆点跟随

小圆点跟随简单,我们也定义一个变量circle,当按钮每点击一次,circle++,然后让对应的圆点填充颜色就行了。

注意,这里和num我们要改善一下边界问题,到达最后一张图片是就不能继续++,要归零才行。

if (circle == 4) {
    circle = 0;
}
else {
    circle++;
}

6.2.2 图片返回

其实,当我们到达最后一张图片再点击是不连贯的,失去了平缓过度的效果。其实,我们可以在最后一张后面克隆第一张图片加上去。

当图片向后移动时,会过渡到最后一张(也就是第一张的克隆版本),这个时候再点击我们就快速回到第一张图片就行了。

//节点操作,复制照片
var cloneimg = ul.children[0].cloneNode(true);
ul.appendChild(cloneimg);

6.3 bug

6-bug.gif

如上图,我们点击圆点到达第三张图,然后点击右侧的按钮,没回到第四张图,为啥又退回了第二张图片。这主要是因为我们ol liindexnum cirle没同步导致的。

如何改善,很简单,把index实时赋值给num cirle就可以改善了。

左侧按钮,直接复制粘贴,改几个数值就行了,我不细讲了。

七、定时器

为了让轮播图按时移动,我们需要在最后加一个定时器效果,其实很简单,定时器内部直接调用右侧按钮的代码就行了。

var timer = this.setInterval(function () {
        rt.click();
    }, 1000);

7-rotate.gif

每次间隔一秒,图片向右移动一张,鼠标接触,停止轮播图,鼠标移开,继续轮播图。

八、总结

本篇文章主要实现了一个简易的轮播图效果,下次再见!

25.gif

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

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

相关文章

【 OpenGauss源码学习 —— 列存储(analyze)(四)】

列存储&#xff08;analyze&#xff09; AcquireSampleCStoreRows 函数es_get_attnums_to_analyze 函数CStoreRelGetCUNumByNow 函数CStore::GetLivedRowNumbers 函数InitGetValFunc 函数CStoreGetfstColIdx 函数CStore::GetCUDesc 函数CStore::IsTheWholeCuDeleted 函数CStore…

学习Bootstrap 5的第七天

目录 徽章 徽章 实例 上下文徽章 实例 胶囊徽章 实例 元素内的徽章 实例 进度条 基础进度条 实例 进度条高度 实例 彩色进度条 实例 条纹进度条 实例 动画进度条 实例 混合色彩进度条 实例 徽章 徽章 在 Bootstrap 中&#xff0c;徽章&#xff08;Badg…

【动手学深度学习】--文本预处理

文章目录 文本预处理1.读取数据集2.词元化3.词表4.整合所有功能 文本预处理 学习视频&#xff1a;文本预处理【动手学深度学习v2】 官方笔记&#xff1a;文本预处理 对于序列数据处理问题&#xff0c;在【序列模型】中评估了所需的统计工具和预测时面临的挑战&#xff0c;这…

2023年8月| 红帽RHCE考试战报-微思红帽官方授权培训中心

2023.8.15 新出炉一波红帽考试战报 恭喜微思10位学员顺利PASS红帽认证考试 通过RHCE认证 不仅从专业技术上证明了你的能力 在职场上更是一块进入Linux行业的“敲门砖” 让你在职场竞争中更具竞争力 微思红帽官方授权培训中心--全国直播&#xff0c;就近安排考试&#xff…

【技巧】安装 win11 必须联网?无法跳过?

安装 Win11 时自动检查更新或者让连接网络&#xff0c;没有提供取消按钮&#xff0c;之前有【我没有 Internet 连接】选项。 在这个界面按 ShiftF10 打开命令提示符 输入OOBE\BYPASSNRO 按回车。 回车之后之后系统会重新启动&#xff0c;此时发现下一步的左侧出现了熟悉的【我…

Matlab论文插图绘制模板第112期—带阴影标记的图

之前的文章中&#xff0c;分享了Matlab带线标记的图&#xff1a; 进一步&#xff0c;本期分享的是带阴影标记的图。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;本期内容『数据代码』已上传资源群中&#xff0c;加群的朋友请自行下载。有需要的朋友可以关注同名公号…

MCP2515调试心得

基于 STM32 芯片的 MCP2515 芯片调试心得 1. MCP2515 芯片解析1.1 外部时钟源1.2 可采用连续传输提高效率发送数据时&#xff0c;使用 TX0 为例&#xff1a; 1.3 关于 MASK 和 Filter 的注意事项1.3.1 Filter 的注意事项1.3.2 MASK 设置的一些问题 2. STM32 硬件 SPI 问题 1. M…

外滩大会发布银行数字化5大趋势:随身银行、AI风控、数字员工、边缘物联与云原生

通用人工智能风起云涌&#xff0c;金融行业将如何应对&#xff1f; 9月8日&#xff0c;由中国银行业协会指导&#xff0c;网商银行承办的外滩大会银行业数字化论坛上&#xff0c;IDC中国副总裁兼首席分析师武连峰发布了《银行数字科技五大趋势》&#xff1a;随身银行、AI风控、…

ULN2003 芯片

芯片介绍&#xff1a; ULN2003 是高耐压、大电流达林顿陈列&#xff0c;由七个硅 NPN 达林顿管组成。 达林顿管并联可以承受更大的电流。 此电路主要应用于继电器驱动器&#xff0c;字锤驱动器&#xff0c;灯驱动器&#xff0c;显示驱动器&#xff08;LED 气 体放电&#…

Apache Tomcat 漏洞复现

文章目录 Apache Tomcat 漏洞复现1. Tomcat7 弱密码和后端 Getshell 漏洞1.1 漏洞描述1.2 漏洞复现1.3 漏洞利用1.3.1 jsp小马1.3.2 jsp大马 2. Aapache Tomcat AJP任意文件读取/包含漏洞2.1 漏洞描述2.1 漏洞复现2.2 漏洞利用工具 3. 通过 PUT 方法的 Tomcat 任意写入文件漏洞…

10元/月?中国电信推出手机直连卫星功能,华为联合开启卫星之旅

2021年9月8日&#xff0c;华为Mate 60 Pro 系列手机首次推出“卫星语音通话”功能。此功能需与运营商合作&#xff0c;而中国电信率先推出了“手机直连卫星”服务。 中国电信的用户可以在自己的普通手机卡套餐基础上&#xff0c;加装直连卫星服务。此项服务的价格如下&#xff…

时序数据库 TimescaleDB 基础概念

时序数据在许多领域中具有广泛的应用&#xff0c;例如金融市场分析、气象预测、交通流量监测、生产过程监控等&#xff0c;时序数据通常是大规模的、高维度的、需要实时计算和分析&#xff0c;针对时序数据的特点与其所带来的挑战&#xff0c;针对时序数据处理所面临的挑战&…

1000元订金?华为折叠屏手机MateX5今日开始预订,售价尚未公布

华为最新款折叠屏手机Mate X5今日在华为商城开始预订&#xff0c;吸引了众多消费者的关注。预订时需交纳1000元的订金&#xff0c;而具体售价尚未公布。据华为商城配置表显示&#xff0c;Mate X5预计将搭载Mate 60系列同款麒麟9000S处理器&#xff0c;或可能搭载麒麟9100处理器…

vue3:4、组合式API-setup选项

setup每次都要return&#xff0c;好麻烦。怎么解决&#xff1f; 使用 <script setup> 语法糖&#xff08;底层帮你return了&#xff09; 写法如下

在线实时监测离子风机的功能

离子风机是一种能够通过释放大量负离子来净化空气并提供清新环境的设备。要实现联网实时在线监测离子风机&#xff0c;可以考虑以下几个步骤&#xff1a; 1. 设备接入互联网&#xff1a;离子风机需要具备网络连接功能&#xff0c;可以通过无线网络或者以太网接入路由器&#x…

优思学院|质量工程师和QA区别在哪?质量工程师有什么发展策略?

质量管理內容相当复杂&#xff0c;从供应商中选择SQE&#xff0c;入料检验的IQC&#xff0c;制程管控的IPQC&#xff0c;站在客户的立场&#xff0c;保证出货质量OQC&#xff0c;所以一般来说QC/QA人员必须管理从材料到出货的所有质量项目。 而质量工程师&#xff08;QE&#…

2023国赛数学建模C题模型代码

C题代码全部都完成了&#xff0c;可以看文末名片 我们先看C题的一个背景 在生鲜商超中,蔬菜类商品保鲜期短,且品相会随销售时间增加而变差。商超需要根据历史销售和需求每天进行补货。由于蔬菜品种众多、产地不同,补货时间在凌晨,商家须在不明确具体单品和价格的情况下进行补…

读书笔记:多Transformer的双向编码器表示法(Bert)-1

多Transformer的双向编码器表示法 Bidirectional Encoder Representations from Transformers&#xff0c;即Bert&#xff1b; 本笔记主要是对谷歌Bert架构的入门学习&#xff1a; 介绍Transformer架构&#xff0c;理解编码器和解码器的工作原理&#xff1b;掌握Bert模型架构…

Tableau自学四部曲_Part4:BI仪表盘搭建

文章目录 一、数据可视化原则1. 区分用户2. 主次分明、详略得当3. 真实准确4. 符合大众认知和审美习惯5. 适度原则6. 五秒原则6. 恰到好处的说明7. 少即是多8. 可视化案例 二、BI仪表盘搭建1. 仪表盘搭建原则2. 明确仪表盘主题3. 仪表盘主题拆解4. 开发设计工作表5. 构思仪表盘…

LQR 控制器

LQR&#xff08;Linear Quadratic Regulator&#xff09;控制器 LQR&#xff08;Linear Quadratic Regulator&#xff09;是一种经典的线性控制器设计方法&#xff0c;用于设计线性时不变系统的状态反馈控制器&#xff0c;以最小化系统性能指标&#xff0c;通常是二次代价函数…