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:
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
虽然现在jQuery用得越来越少(我也不愿意写),但是不得不说在做公司官网这种以展示为主的项目,用jQuery还是首选,所以熟悉一下也不吃亏是吧,嘻嘻。
作者微信:Aqing1906
欢迎指教哦
1
2
3
1
2
3
发表评论 (审核通过后显示评论):