jQuery实现自动切换动画

test2 (1).gif image.png gif压缩得太厉害了,可能看不清或者加载不出,大家可以到我司官网看看效果,点击这里进入官网 不知道这种效果是不是你们想要的效果,这是超人鸭开发公司官网遇到的一个需求,结合上面的动图梳理一下需求: 一进页面动画会自动执行,且是循环执行。 分为三项,中间以类似进度条的元素连接,主要动画也是这个进度条。 上面第几个图标激活时,下面显示对应的内容。 点击上面的图标时,下面内容做对应切换,同时停止动画不再执行,进度条也不显示。 这就是大概的需求,那如何实现呢,我进行了简单的分析: 上面的进度条动画用到jquery中的animate方法,一开始将进度条的宽度设置为零,在一定的时间内将宽度变成100%,激活对应的图标,同时在动画开始时要将其他的进度条宽度设置为零。下面内容的切换根据上面的激活的图标是第几个进行显示,问题的关键就是如何知道激活的图标是第几个,也就是index,在激活的图标改变时下面的内容也要跟着改变,所以就要监听这个index的变化,在它变化时做出相应的操作,那在js中监听一个变量的变化我用到的是Object.defineProperty(),用它来改写对象属性的get和set,不了解这个api的朋友可以翻阅一下,不难理解。 下面我就一步一步现实这个自动切换的动画效果,首先是上面控制的图标与进度条html和css,这个dom结构看清楚可以提升文章观看体验: html:
css: 效果: image.png 接下来是实现动画,上面说到,要去监听一个变量的变化,代表上面图标的index,当它改变时去做相应的操作,所以先来监听一个变量: var indexObj = {} var temp = null Object.defineProperty(indexObj, 'index', { get: function() { return temp }, set: function(value) { temp = value // 执行某些操作 setActive(temp) } }); 其中temp是一个中间变量,因为我们要取这个index,也就是执行get方法,如果在get里面直接return这个属性,那return 的时候相当会再执行一次get,就会陷入死循环,最后报错: var indexObj = {} var temp = null Object.defineProperty(indexObj, 'index', { get: function() { return this.index }, set: function(value) { temp = value // 执行某些操作 setActive(temp) } }); indexObj.index = 0 console.log(indexObj.index) image.png 所以使用要使用get的时候需要一个临时变量,return这个临时变量temp。到这里我们就能监听一个变量的变化了,它代表着当前激活的是第几个图标,也就是index,当它改变时我们去执行setActive这个方法,并把index传进去: function setActive(val) { // $(".process-item")就是代表上面的图标(圆点) $(".process-item").removeClass('active') // eq里面写变量需要像这样写,不然会被识别成字符串 $(".process-item:eq("+(val)+")").addClass('active') } 接下来就是进度条的动画了,当进度条动画执行完后,index+1,图标的激活样式就会自动改变,因为我们已经监听了它的变化,这里用到jQuery的animate方法,而且用到了它的回调函数,用法是这样: $(selector).animate(styles,speed,easing,callback) 第三个参数我忽略掉了,看看例子: $('div').animate({width:'100%'},1000,function(){alert()}) 表示选中div元素在一秒内宽度变成100%,完成后alert() 初步实现进度条动画: function setLineWidth(){ // 动画开始前将其他进度条清空 $(".active-line").not(".active-line:eq("+(indexObj.index)+")").css("width",'0px') $(".active-line:eq("+(indexObj.index)+")").animate({width:'100%'},1000,function() { indexObj.index += 1 setLineWidth() // 再次执行 }) } setLineWidth() 这样是能执行一遍动画,但是以我的图片例子,进度条只有两个,所以操作进度条的index最大只能是1,而上面的图标(圆点)包括内容有三个,所以操作他们的index最大只能是2,配合动画循环的需求,我改写一下监听index的方法: Object.defineProperty(indexObj, 'index', { get: function() { return temp }, set: function(value) { if(value===3){ temp = 0 } temp = value // 执行某些操作 setActive(temp) } }); 加个判断让index可以在0到2之间循环,但是操作进度条的index最大只能是1,当index=2的时候,应该不操作进度条,改写一下上面的setLineWidth方法: function setLineWidth(){ // 动画开始前将其他进度条清空 $(".active-line").not(".active-line:eq("+(indexObj.index)+")").css("width",'0px') if(indexObj.index < 2) { $(".active-line:eq("+(indexObj.index)+")").animate({width:'100%'},1000,function() { indexObj.index += 1 setLineWidth() // 再次执行 }) } else { // index等于2的情况 setTimeout(function() { indexObj.index += 1 // 当index=3的时候会自动变成0 setLineWidth() },1000) // 保持一样的时间 } } setLineWidth() 效果: 1.gif 接下来实现点击上面的图标时,内容对应切换,并停止动画: 首先是对应的激活样式切换,这个直接在点击事件里面改变index就可以,然后要停止动画,并且清空进度条,我们先定义一个全局变量,然后在这个点击事件里面改变,并改写上面的setLineWidth方法: var isClick = false // 表示是否点击 $(".process-item").click(function() { $(".active-line").css("display", "none") // 隐藏进度条 isClick = true // 表示点击 indexObj.index = $(".process-item").index(this) // 改变index }) function setLineWidth() { if(isClick) { return } $(".active-line").not(".active-line:eq("+(indexObj.index)+")").css("width",'0px') if(indexObj.index < 2) { $(".active-line:eq("+(indexObj.index)+")").animate({width:'100%'},1000,function() { if(isClick) { return } indexObj.index += 1 setLineWidth() }) } else { setTimeout(function() { if(isClick) { return } indexObj.index += 1 setLineWidth() }, 1000) } } 之所以在里面动画执行完也加了判断是因为动画的执行时间为一秒,那当你点击的时候它可能在执行的过程中,那index还是会改变,这样是不行的,所以每一个步骤都要加上判断,看看现在的效果: 1.gif 到这里,上面的图标控制和进度条动画已经实现了,下面的内容跟着切换其实也是一样,用的还是写好的index逻辑,切换的动画直接用css的过渡就可以实现,下面我简单演示一下,加一下html与css,都是在上面的代码后面直接加上: html:
1
2
3
css: .content-item{ width: 100%; height: 200px; position: absolute; right: -400px; font-size: 30px; opacity: 0; transition: all 0.8s; } .content-item:nth-of-type(1){ background: yellow; } .content-item:nth-of-type(2){ background: blue; } .content-item:nth-of-type(3){ background: red; } .content-item.active{ opacity: 1; right: 0; } 所以只需要根据index切换active这个class就可以了,在setActive方法里面添加切换的代码: function setActive(val) { // $(".process-item")就是代表上面的图标(圆点) $(".process-item").removeClass('active') // eq里面写变量需要像这样写,不然会被识别成字符串 $(".process-item:eq("+(val)+")").addClass('active') $(".content-item").removeClass('active') $(".content-item:eq("+(val)+")").addClass('active') } 效果: 1.gif 到这里完整的效果已经实现了,下面是完整的代码: Document
1
2
3
虽然现在jQuery用得越来越少(我也不愿意写),但是不得不说在做公司官网这种以展示为主的项目,用jQuery还是首选,所以熟悉一下也不吃亏是吧,嘻嘻。 作者微信:Aqing1906 欢迎指教哦

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):