原生js实现旋转木马效果的轮播图
实现效果


实现分析:
效果分析:
①鼠标移入轮播图后显示左右箭头,鼠标移出轮播图后会隐藏左右箭头
②通过实现效果分析,可得出该5张轮播图的图片设置了5中不同的样式,我们可 以将该五种样式保存到数组中,方便每次点击箭头时对每张图的样式进行切换
代码分析:
①先封装一个动画函数,以便于点击时使用该函数进行图片的切换
由于需要考虑到复用性,可能传递到动画的参数都不一样,如实现动画效果的对象、动画改变的参数(如:上下左右移动,宽度、高度、透明度变化等)。
【如:在本次轮播图中,需要改变的是 宽:width ;离父元素的上侧距离top;离父元素的左侧边距离 left ;透明度opacity 层级 z-index】
因此:我们应该设置如下三个参数:动画对象、该对象需要改变的参数对象(即:以防止以后复用该动画函数时传递过来的参数不包含本次用到的属性,如:将该对象需要在本次动画所改变的参数width、top、left、opacity、z-index放到对象参数中)和回调函数callback(防止某些动画的开始的前提是在本次运动后才能执行或者结束本次动画时需要执行其他操作)
function slowDown(obj, options, callback) {//在执行本次动画前,先清除定时器,避免上一次定时器影响clearInterval(obj.timer)obj.timer = setInterval(function () {// 假设都到目标位置let flag = true;// 用for..in..循环遍历optionsfor (let attr in options) {// 处理opacity//判断本次获取到的对象属性是否为opacity(即:透明度)if (attr == 'opacity') {//因为透明度的取值范围为0-1,因此防止下面取整所影响,所以需要乘100//target为目标值let target = options[attr] * 100//由于obj.style只能获取到行内设置的样式//通过getComputedStyle(obj)可以获取obj中的css样式值let curV = getComputedStyle(obj)[attr] * 100//step为步长,即每次运动的长度,除10可以更改,这里就用每次走总数的十分之一为例let step = (target - curV) / 10// 根据运动方向来决定是向右取整还是向左取整step = step >= 0 ? Math.ceil(step) : Math.floor(step);// 移动后位置//由于上面乘了100,所以这里需要除100//nextV为本次动画的所需达到的值let nextV = (curV + step) / 100//将本次动画的所需达到的值赋值给该动画对象的属性中obj.style[attr] = nextV// 判断只要有一个没有到达目标值就继续if (nextV * 100 != target) {flag = false}//如果该对象属性为层级zindex,则直接赋值即可,因为层级是直接设置的,没有动画效果} else if (attr === 'zIndex' || attr === 'z-index') {obj.style.zIndex = options[attr]} else {//如果是其他属性(因为本次案例中,只有z-index和opacity是不带单位的,其他属性需要有px)let target = options[attr]let curV = parseInt(getComputedStyle(obj)[attr])let step = (target - curV) / 10// 根据方向来决定是向右取整,还是向左取整step = step >= 0 ? Math.ceil(step) : Math.floor(step);let nextV = curV + step;obj.style[attr] = nextV + 'px';// 判断只要有1个没有到达目标值就if (nextV != target) {flag = false;}}}//判断是否所有属性都达到了目标值if (flag) {//如果都达到即停止定时器clearInterval(obj.timer);//判断是否传递进来其他回调函数if (typeof (callback) === 'function') {callback();}}}, 30);}
②获取需要操作的元素对象
// 获取操作的元素//装轮播图的父元素let oWrap = document.querySelector('.wrap');//装轮播图中左右箭头的父元素let oArrow = document.querySelector('.arrow');//右箭头元素let oRight = document.querySelector('#arrRight');//左箭头元素let oLeft = document.querySelector('#arrLeft');//装轮播图图片的lilet oLis = document.querySelectorAll('.wrap li');
③移入轮播图时显示左右箭头
为装轮播图的父元素oWrap 绑定鼠标移入onmouseover、移出事件onmouseout,鼠标移入轮播图时,显示左右箭头,移出时隐藏轮播图,这里通过改变父元素oWrap 的opacity值来实现
// 鼠标移入事件oWrap.onmouseover = function () {oArrow.style.opacity = 1;}oWrap.onmouseout = function () {oArrow.style.opacity = 0;}
④切换时需要用到的样式数组
// 当前效果,有5组样式let config = [{width: 600,top: 70,left: 600,opacity: 0.8,'z-index': 3},{width: 400,top: 20,left: 750,opacity: 0.2,'z-index': 2},{width: 400,top: 20,left: 50,opacity: 0.2,'z-index': 2},{width: 600,top: 70,left: 0,opacity: 0.8,'z-index': 3},{width: 800,top: 120,left: 200,opacity: 1,'z-index': 4}];
⑤为每个li设置样式
通过for循环,将放轮播图的图片的li设置对应的样式
function setStyle(){// 创建一个函数,为每个li应用相应的样式for(let i=0;i
⑥为左右箭头绑定点击事件
每次点击时,调用上面的setStyle()函数,为li重新赋值
oLeft.onclick=function(){// 将样式组件里的最后的元素移动到和数组的头部config.unshift(config.pop())setStyle()}oRight.onclick = function(){// 将样式数组里的前面的元素移动到数组的尾部config.push(config.shift());setStyle();}
完整代码
HTML部分:
CSS部分:
/*初始化 reset*/* {margin: 0;padding: 0}body {font: 12px/1.5 "Microsoft YaHei", "微软雅黑", SimSun, "宋体", sans-serif;color: #666;}ol,ul {list-style: none}a {text-decoration: none}img {border: 0;vertical-align: top;}textarea {outline: none;}a,button {cursor: pointer;}.wrap {width: 1200px;margin: 100px auto;border: 1px solid red;}.slide {height: 500px;position: relative;}.slide li {position: absolute;left: 200px;top: 0;}.slide li img {width: 100%;}.arrow {opacity: 0;}.prev,.next {width: 76px;height: 112px;position: absolute;top: 50%;margin-top: -56px;/*background-color: red;*/background: url(./images/prev.png) no-repeat;z-index: 99;}.next {right: 0;background-image: url(./images/next.png);}
JS部分:
// 当前效果,有5组样式let config = [{width: 600,top: 70,left: 600,opacity: 0.8,'z-index': 3},{width: 400,top: 20,left: 750,opacity: 0.2,'z-index': 2},{width: 400,top: 20,left: 50,opacity: 0.2,'z-index': 2},{width: 600,top: 70,left: 0,opacity: 0.8,'z-index': 3},{width: 800,top: 120,left: 200,opacity: 1,'z-index': 4}];// 获取操作的元素let oWrap = document.querySelector('.wrap');let oArrow = document.querySelector('.arrow');let oRight = document.querySelector('#arrRight');let oLeft = document.querySelector('#arrLeft');let oLis = document.querySelectorAll('.wrap li');// 鼠标移入事件oWrap.onmouseover = function () {oArrow.style.opacity = 1;}oWrap.onmouseout = function () {oArrow.style.opacity = 0;}function setStyle(){// 创建一个函数,为每个li应用相应的样式for(let i=0;i= 0 ? Math.ceil(step) : Math.floor(step);// 移动后位置let nextV = (curV + step) / 100obj.style[attr] = nextV// 判断只要有一个没有到达目标值就继续if (nextV * 100 != target) {flag = false}} else if (attr === 'zIndex' || attr === 'z-index') {obj.style.zIndex = options[attr]} else {let target = options[attr]let curV = parseInt(getComputedStyle(obj)[attr])let step = (target - curV) / 10// 根据方向来决定是向右取整,还是向左取整step = step >= 0 ? Math.ceil(step) : Math.floor(step);let nextV = curV + step;obj.style[attr] = nextV + 'px';// 判断只要有1个没有到达目标值就if (nextV != target) {flag = false;}}}if (flag) {clearInterval(obj.timer);if (typeof (callback) === 'function') {callback();}}// console.log(curV,step,nextV);}, 30);}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!





