今天,在写仿网易云音乐播放器的播放页面时,有一些体会,写篇博客记录下来。
我是使用MVC模式写播放页面的JS,需要实现的效果是,
1.一开始光盘中间只出现“播放”按钮,不出现“暂停”按钮,这个很简单,一开始就在css里写死“暂停”按钮display:none;
2.当点击“播放”按钮时,播放音乐,同时 光盘开始转动,出现“暂停”按钮。
3.当点击“暂停”按钮时,停止播放音乐,同时 光盘停止开始转动,出现“播放”按钮。
一开始我的View里面的render()函数只负责将歌曲封面图片渲染进img标签,同时改变背景图片的url,同时View里还有circle()(光盘转动),stopcircle()(光盘停止转动),showPlaybutton()(展现播放按钮),showPausebutton(展现暂停按钮)四个函数,即将每个效果写成一个函数分别调用。
circle(){
$('.cover').css('animation-play-state','running')
//最好不要直接修改CSS,通过添加/删除 class来做到
},
stopcircle(){
$('.cover').css('animation-play-state','paused')
},
showPlaybutton(){
this.$el.find('.disc').removeClass('playing')
},
showPausebutton(){
this.$el.find('.disc').addClass('playing')
}
// css:
.disc.playing .icon-pause{display:block}
.disc.playing .icon-play{display:none}
写完之后发现view太细碎了,需进行优化。
仔细一想,光盘转动+“暂停”按钮 是播放时的一个组合效果,光盘不转动+“播放”按钮 是一个组合(暂停时),那么播放时我用一个变量status记下此时的状态playing ,在render时判断一下,然后按各自的效果渲染就可以了。因此我在model的data里添加了一个status变量。
data:{
song:{
id:'',
name:'',
singer:'',
url:'',
cover:''
},
status:'paused'
},
这样的话,就把上面的四个函数变成了render函数里的:
if(status === 'playing'){
$('.cover').css('animation-play-state','running')
this.$el.find('.disc').addClass('playing')
}else if((status === 'paused')){
$('.cover').css('animation-play-state','paused')
this.$el.find('.disc').removeClass('playing')
}
另外,基于CSS和JS分开管理的原则,尽量不要让JS直接去修改CSS(虽然有.css()
这样的API)而是通过添加类(.addClass(),removeClass()
)来实现切换。因此,通过给.cover和.disc共同的父元素添加/删除 class,将这两个效果都挂载在其父元素.playing
的状态下,这样上面两种情况的两行代码就简化成一行了,
if(status === 'playing'){
this.$el.find('.disc').addClass('playing')
}else if((status === 'paused')){
this.$el.find('.disc').removeClass('playing')
}
至此,对render函数的改造最终完成。
犹如上面的每一步,一开始我的代码可能很low,基本上就是想到什么写什么,但没关系,先实现功能再优化代码也未尝不可嘛!
网友评论