javaScript小案例------js实现无缝轮播图效果篇
原生js书写无缝轮播图
- javaScript无缝轮播图思路及源码
- 无缝轮播图效果
- 总体思路
- 下面附上代码:
- html
- css
- animate.js
- index.js
javaScript无缝轮播图思路及源码
上一章发的都是代码,思路没有写出来,这一章主要是将思路,怎么写的。当然代码在最后哦!图片绝对能滚起来哦。
无缝轮播图效果
总体思路
无缝轮播图在日常生活中随处可见,比如在我们csdn的首页就有无缝轮播图,所以我讲解一下我对无缝轮播图的见解和思路。
- 首先我是从整体分析了一下,我们可以先看一下无缝轮播图的结构样式。其中含有图片若干张,左右箭头,下方指示器。我是先写一个div用来包含所有的元素。图片单独用一个div,左右箭头,指示器都是单独用一个div包含。只不过我考虑到以后工作场景,所以我的图片和指示器都没有在html中显示,只是先写一个看一下样式用于前期的网页测试。
- 然后我开始写css样式,css样式我是首先用到了定位,全部基于第一个写的div定位,然后溢出隐藏。
给图片增加样式,用width的值用%号来写,高度也是这样。一张图片就是占满一个大的div。有几张图片就几个100%。左右箭头都是使用的矢量图标,所以可以font-size调试大小,在调试位置。最后是指示器的相关样式,指示器是行快盒,也可以用浮动来使指示器都在一行上显示。
最后在给指示器增加一个显示第几张就其相对应的指示器显示颜色,即激活指示器。- 然后静态部分写好了。
开始分析如何使图片无缝轮播
顾名思义,无缝轮播,就是必须要有计时器,图片之间的动画不能有缝隙。动画过程中流畅,图片切换自如 。
所以必须要写动画,我是抽离出来了动画的部分,最后直接调用即可。我是先定义了一个函数,用于在别的部分调用这个动画函数,完成动画操作。动画嘛,理所当然就会有起始值,结束值,变化的总时间,动画间隔的时间,和动画在间隔时间的变化次数(变化次数最好要返回整数,小数的画会出现一些不必要的麻烦),然后是动画的每一次的变化改变的值,然后还有变化的次数,函数最后再写个计时器,也是这个动画函数的核心部分,动画首先都是起始值加上上一次变化的值,然后变化的次数在增加一次,做一下判断,变化的次数是不是达到了变化的总次数,然后表示变化完成了,就清除这个计时器,表示动画完成了,不需要变化了,然后调用一下表示动画开始的函数和动画结束的函数。最后在写一个无数的可能性,就是表示动画开始的函数和传入一个参数from。用于调用动画开始。- 最后就是js的基础部分。
写js基础部分的时候,我是先思考一下,要怎么开始写,从哪里开始下手写。
我考虑到图片路径,(为了以便更好的贴合实际工作需求)所以我是把图片放在一个数组中了,以便写指示器和图片的相关操作。
我要先定义一个全局变量表示当前显示的是第几张图片,索引操作。然后开始写一个函数,用于创建图片到容器中,在设置一个容器div的宽度,因为包裹图片的容器,宽度取决于内部图片的数量,然后再创建指示器,根据我定义的那个全局变量(表示当前显示的是第几张图片)来设置指示器的激活(变色)状态。
然后再写一个函数,在函数中定义一个我要切换到图片索引的变量,再计算容器的marginLeft,将容器从当前的marfinLeft变化到新的marginLeft,
(为什么要用marginLeft纳?因为图片是这个容器中的一部分,而css中把图片的大小等于了n00%,所以可以用这个)
再更新全局变量(表示当前显示的是第几张图片)的值,就是等于我要切换到的图片索引的变量,最后再更改一个指示器的状态。
然后再写两个函数,表示向前切换一张图片,向后切换一张图片,就是无缝切换到下一张或者上一张图片,然后调用我写的那个表示切换图片的函数,然后再向下一张图片切换的函数中最后写道最后一张图片切换完成后要回归到第一张,相反,向上切换一张就是从第一张图片开始切换,先跳到最后一张的图片,再进行无缝切换。
最后开始鼠标点击事件和移动事件,首先是左右箭头写事件,再写开始动画无缝轮播,停止动画无缝轮播,然后写鼠标移动事件,移动到图片上去停止动画轮播,移开开始播放动画。
下面附上代码:
html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>无缝轮播图</title><!-- css引用地址 --><link rel="stylesheet" href="./index.css"><!-- 矢量图标引用地址 --><link rel="stylesheet" href="//at.alicdn.com/t/font_3281875_e4prwerl5ms.css">
</head><body><div class="carousel-container"><!-- 图片 --><div class="carousel-list"><!-- 图片 --><!-- <img src="./image/Wallpaper1.jpg" alt="" class="carousel-item"> --></div><!-- 左箭头 --><div class="arrow-left"><!-- 如要更改左箭头,改这里哦 --><i class="iconfont icon-lunbotujiantou-"></i></div><!-- 右箭头 --><div class="arrow-right"><!-- 如要更改右箭头,改这里哦 --><i class="iconfont icon-lunbotujiantou-1"></i></div><!-- 指示器 --><div class="indicator"><!-- 未激活的指示器 --><!-- <span class="indicator-item"></span> --><!-- 已经激活的指示器 --><!-- <span class="indicator-item select"></span> --></div></div><!-- js引用地址 --><script src="./js/animate.js"></script><script src="./js/index.js"></script>
</body></html>
css
* {margin: 0;padding: 0;box-sizing: border-box;
}.carousel-container {position: relative;width: 500px;height: 300px;/* outline: 1px solid; */margin: 0 auto;margin-top: 20px;overflow: hidden;
}/* 图片的相关样式 */.carousel-list {width: 500%;height: 100%;
}.carousel-item {width: 500px;height: 100%;object-fit: cover;
}/* 左右箭头相关样式及背景样式 */.arrow-left,
.arrow-right {position: absolute;background-color: rgba(0, 0, 0, 0.2);width: 50px;height: 100%;top: 0;color: #fff;text-align: center;line-height: 300px;
}.arrow-left:hover,
.arrow-right:hover {background-color: rgba(0, 0, 0, 0.5);
}.arrow-left i {cursor: pointer;
}.arrow-right i {cursor: pointer;
}.arrow-left {left: 0;
}.arrow-right {right: 0;
}/* 指示器的相关样式 */.indicator {position: absolute;width: 100%;height: 50px;bottom: 0px;text-align: center;background-color: rgba(0, 0, 0, 0);
}/* 未激活的指示器的样式 */.indicator-item {display: inline-block;width: 20px;height: 3px;background: #fff;cursor: pointer;margin: 0 5px;
}/* 激活指示器的样式 */.indicator-item.select {background: #ffa44f;
}
animate.js
function createAnimation(options) {// 起始值var from = options.from;// 结束值var to = options.to;// 变化总时间var totalMS = options.totalMS || 1000;// 动画间隔时间var duration = options.duration || 15;// 变化的次数var times = Math.floor(totalMS / duration);// 每一次变化改变的值var dis = (to - from) / times;// 当前变化的次数var curTimes = 0;var timerId = setInterval(function() {// 变化的起始值加上每一次变化的值。from += dis;// 当前变化增加一次curTimes++;if (curTimes >= times) {// 变化的次数达到了from = to; // 变化完成了clearInterval(timerId); // 不再变化了options.onmove && options.onmove(from);options.onend && options.onend();return;}// 无数的可能性options.onmove && options.onmove(from);}, duration);
}
index.js
(function() {// 创建图片数组var img = ['./image/Wallpaper1.jpg','./image/Wallpaper2.jpg','./image/Wallpaper3.jpg','./image/Wallpaper4.jpg','./image/Wallpaper5.jpg',];// 封装document.querySelectorfunction $(selector) {return document.querySelector(selector);}// 获取需要元素的domvar doms = {container: $('.carousel-container'),list: $('.carousel-list'),arrowLeft: $('.icon-lunbotujiantou-'),arrowRight: $('.icon-lunbotujiantou-1'),indicator: $('.indicator')};// 初始化// console.log(dom.list);// 当前显示的是第几张图片var curIndex = 0;function init() {// 创建图片function createImg(srcImg) {// 创建img元素var createImgs = document.createElement('img');// 给img元素的src属性赋值,createImgs.src = srcImg;// 给img元素的class选择器属性写值createImgs.className = 'carousel-item';// 将img元素添加进class选择器为carousel-list的里面doms.list.appendChild(createImgs);}// 遍历img数组,for (var i = 0; i < img.length; i++) {// 调用createImg函数,img[i]表示的就是img数组中表示的所有的图片地址,并传入createImg函数。createImg(img[i]);}// 将第一张图片在最后重新添加一次createImg(img[0]);// 设置容器的宽度,doms.list.style.width = doms.list.children.length + '00%';// 创建指示器/* function newindicator(span) {var span = document.createElement('span');// console.log(span);span.className = 'indicator-item';doms.indicator.appendChild(span);// for (var j = 0; j < img.length; j++) {// }// span.classNama = 'indicator-item';// doms.indicator.appendChild(span);} */function indicarors(span) {// 创建span标签var span = document.createElement('span');// 给span标签的class选择器写入值span.className = 'indicator-item';// 将span元素添加进class选择器为indicator的里面doms.indicator.appendChild(span);}// 同上面的操作一样,表示img数组中有几张图片就会有几个span标签for (var i = 0; i < img.length; i++) {indicarors(img[i]);}// 将第一张图片在最后重新添加一次// createImg(img[0]);// 设置指示器的激活状态activationIndicator();}// 调用init函数,将视口内容显示出来init();// 指示器的状态/* var act = $('.indicator-item.select');console.log(act); */function activationIndicator() {// 先清除已经激活的指示器// 先获取有显示激活指示器的样式的domvar act = $('.indicator-item.select');// 判断是否有激活指示器的domif (act) {// 如果有就把激活指示器的样式换成没有激活的状态act.className = 'indicator-item';}//激活指示器的颜色// 改变图片var index = curIndex;// 如果图片大于所有图片if (index > img.length - 1) {// 就把图片改变为0,第一张index = 0;}// 改变当前图片的对应的指示器样式,激活它。doms.indicator.children[index].className = 'indicator-item select';}// 获取到视口的宽度var containerWidth = doms.container.clientWidth;// console.log(containerWidth);// 动画总时间var totalMS = 1000;// 表示动画的效果是否运行var isPlaying = false;function moveTo(newIndex, onend) {// 如果动画正在运行if (isPlaying) {// 就返回,不做任何执行操作return;}// 如果要没有动画,所以要把动画设为true,告诉下面动画要执行了。isPlaying = true;// newIndex为要切换的图片索引// 计算图片容器的marginLeft// 将图片的mariginLeft变化到新的marginLeft// 更新curIndex的值// 更改指示器的状态createAnimation({// 当前时刻的起始值,是class选择器为carousel-list的marginLeft元素,取整数,如果没有就取0。from: parseFloat(doms.list.style.marginLeft) || 0,// 最终的:要切换的图片索引去乘以获取到的视口宽度to: -newIndex * containerWidth,totalMs: totalMS,// n表示的就是marginLeft值// 开始动画onmove: function(n) {// console.log(n);// 改变class选择器为carousel-list的marginLeft值doms.list.style.marginLeft = n + 'px';},// 终止动画onend: function() {// 将动画变成false,就是没有运行动画isPlaying = false;// 动画完成后调用这个onend函数,不传入参数,就不调用了onend && onend();},})// 更新图片的索引curIndex = newIndex;// 调用激活指示器的状态函数,用来设置指示器的状态(显示第几张,它对应的指示器就是激活状态)activationIndicator();}function next() {// 无缝切换到下一张图片// 调用moveTo函数进行切换// 最后一张图片切换完成后回归到第一张// 切换到最后一张图片了// 等动画完成后,要回到第一张图片// 新的图片下标变为原来的图片下标+1var newIndex = curIndex + 1;// 变量的提升,定义一下onend。现在为undefinedvar onend;// 新的图片是否等于class选择器值为carousel-list的元素的子元素的长度-1,就是最后一张图片if (newIndex === doms.list.children.length - 1) {// 给onend赋值onend = function() {// 将marginLeft设为0,就是回到了第一张图片doms.list.style.marginLeft = 0;// 改变当前的图片为0.curIndex = 0;};};// 调用moveTo函数。执行相关的操作moveTo(newIndex, onend);}function prev() {// 无缝切换到上一张图片// 调用moveTo函数进行切换// 从第一张图片开始进行切换时,先跳到最后一张的位置,在进行切换// 定义新的图片下标var newIndex = curIndex - 1;// 如果图片下标小于0if (newIndex < 0) {// 就定义最大的图片下标var maxIndex = doms.list.children.length - 1;// 设置marginLeft的大小为负的最大的图片下标乘以视口的宽度doms.list.style.marginLeft = -maxIndex * containerWidth + 'px';// 然后新的图片下标是最大下标-1newIndex = maxIndex - 1;}// 调用moveTo函数moveTo(newIndex);}// 处理指示器的点击事件for (var i = 0; i < doms.indicator.children.length; i++) {// 立即执行函数,(function(i) {doms.indicator.children[i].onclick = function() {moveTo(i);};})(i);}// 点击左箭头向前一张doms.arrowLeft.onclick = prev;// 点击右箭头向右一张doms.arrowRight.onclick = next;// 定义计时器Idvar timeId;// 间隔时间var durations = 2000;// 开始function start() {// 如果有计时器 已经有自动切换在进行if (timeId) {// 返回,啥都不干return;}// 设置向下一张的计时器timeId = setInterval(next, durations);}// 最开始自动切换start();// 停止function stop() {// 清除计时器clearInterval(timeId);// 计时器赋值为空。timeId = null;}// 鼠标事件// 鼠标移动上去停止播放动画doms.container.onmouseenter = stop;// 鼠标移开开始播放动画doms.container.onmouseleave = start;
})()
若有错误,欢迎大佬们来给我指正哟!
javaScript小案例------js实现无缝轮播图效果篇相关推荐
- javaScript小案例------js实现手风琴效果篇
原生js书写手风琴效果 js手风琴效果 第一种方法 手风琴需求 html和css: html: css: js animate.js index.js 第二种方法 js手风琴效果 我用了两种方法来完成 ...
- JavaScript实现无缝轮播图效果
通过原生js实现无缝轮播效果. 思路: 1.利用html+css完成轮播图片,按钮,底部小点的整体效果的布局. 2.通过原生js完成图片轮播,无缝自动切换,底部小点随图片切换而切换. 步骤1: 建立无 ...
- 原生js进阶版轮播图实现(走马灯效果,无缝衔接)
原生js进阶版轮播图实现(走马灯效果,无缝衔接) 利用原生js手写一个轮播图,是上一篇文章的简易版的一个进阶,本次轮播图主要是利用定位和定时器实现了走马灯效果,并且是左右轮播.实现过程与代码也是很简单 ...
- 左右无缝轮播html,JS实现左右无缝轮播图代码
废话不多说了,直接给大家贴代码了. 无缝轮播图: 无缝轮播图 *{margin: 0;padding:0; } ul{list-style: none;} .banner{width: 600px;h ...
- 例子---JS无缝轮播图
DuangDuang,今天我们来一起说说JS实现无缝轮播.没错,顾名思义,就是我们脑子中浮现的类似淘宝主页面中间部分的那个滚动图.这个轮播图的使用频率还是很大的,所以还是很有必要好好研究一下的. 哈哈 ...
- 原生JS无缝轮播图(左右切换、导航跟随)
原生JS无缝轮播图(左右切换.导航图标) 功能: 1.实现轮播图的左右无缝切换 2.实现导航图标的跟随显示.点击切换 3.使用定时器进行无缝轮播 css部分 <style>/* 轮播图容器 ...
- jquery实现动态左右无缝轮播图
JQ代码实现动态无缝轮播图功能 相比之下 运用jquery比js原生代码 书写更为方便 简介 通俗易懂 以下为代码: <!DOCTYPE html> <html><hea ...
- 左右无缝轮播图的实现
无缝轮播图: <title>无缝轮播图</title><style>*{margin: 0;padding:0; }ul{list-style: none;}.ba ...
- jq 实现无缝轮播图
工作中经常会用到轮播图,这里记载两种轮播图,供大家参考 一.自动播放的无缝轮播图(一张图片占满屏) 首先是HTML, <div class='bannerCon'><ul class ...
最新文章
- 3.5 向量化实现的解释-深度学习-Stanford吴恩达教授
- Springboot中艾特Controller和艾特RestController之间的区别
- some understanding of《Inferring Decision Trees Using the Minimum Description Length Principle*》
- android 中文api 在线测试,android webview测试方法
- EditPlus3 添加 PHP代码格式化
- 【Uva - 10935】 Throwing cards away I (既然是I,看来还有Ⅱ、Ⅲ、Ⅳ?)(站队问题队列问题)
- IDEA如何设置背景色?
- IDEA的Mybatis插件
- Mac版idea快速切换大小写快捷键
- 计算机win764位相机驱动,Win7万能驱动64位
- echarts折线图标识最大值
- 计算机休眠后无法联网,电脑休眠后回来就不能上网了
- centos7对普通用户授权sudo权限
- 帝国CMS采集插件哪个好用?帝国CMS采集文章教程
- 通过URL在前端页面传参的方法
- Unity 《愤怒的小鸟》涉及的主要知识
- a标签的带参传值和form表单的带参
- leetCode876
- RPA优势解密丨到底能做什么?为何深受追捧?
- python 入门题库————python语句和基础数理