走马灯这么基础的效果,没必要动用jQuery插件,jQuery本身就已经很强大了好么?
概述
首先构建一个静态的ul,然后通过jQuery的.animate()方法来控制ul的margin来实现滚动,横向滚动是控制margin-left,纵向滚动则是控制margin-top。动画执行之后,在回调里巧妙的使用两行语句就OK了。就这么简单。
这个思路的优势:
不借助CSS3,兼容性好。
不借助绝对定位,容易理解。
给margin-left设置负值属于正当的CSS规范写法,不属于hack,兼容性可以放心。
下面先以横向走马灯为例。
横向走马灯
准备ul列表
由于要保证ul在margin-left为负值的时候被父元素修剪,所以必须给ul搞一个父元素,而且父元素设置overflow:hidden;。基于组件化的考虑,这个父元素应该是本组件的元素之一,所以,单独搞一个父元素比较好。
HTML代码:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
CSS代码
.content{
width: 960px;
height:120px; /* 高度值一般就是一个li的盒子高度 */
overflow: hidden;
border: #333 solid 1px;
margin: auto;
}
.content ul{
margin: 0;
padding: 0;
width: 200%; /* 不一定非要200%,只要比100%多出一个li盒子宽度即可,但由于最极端的宽度也就是显示一个li,再多出一个li,一共两个li,所以最合适的值是200% */
height:100%;
}
.content ul li{
list-style: none;
float: left;
width: 108px;
height: 108px;
border: #ccc solid 1px;
display: block;
margin: 5px;
}
CSS代码都是最简化的,不解释了。
JS代码
引用jQuery:
JS:
function scroll() {
$(".content ul").animate({"margin-left":"-120px"}, function() {
$(".content ul li:eq(0)").appendTo($(".content ul"));
$(".content ul").css({"margin-left": 0});
});
}
var scrolling = setInterval(scroll, 1000);
$('.content').hover(function() {
clearInterval(scrolling);
}, function() {
scrolling = setInterval(scroll, 1000);
});
这段JS就好玩了:
先说“-120px”是哪里算出来的:一个li的盒子宽度:108+5+5+1+1=120px。
然后说一下.animate()的参数:
animate(params,[speed],[easing],[fn])
params: 一组包含作为动画属性和终值的样式属性和及其值的集合
speed: 三种预定速度之一的字符串("slow","normal", or "fast")或表示动画时长的毫秒数值(如:1000)
easing: 要使用的擦除效果的名称(需要插件支持).默认jQuery提供"linear" 和 "swing".
fn:在动画完成时执行的函数,每个元素执行一次。
JS的执行过程是:
1、先让ul向左移动120px,简单说就是,让ul以.animate()的默认速度向左移动120px。这一步执行完成之后,界面暂时是这样的,1号li已经出界,由于ul元素是被裁减的,所以1号li被隐藏:
Paste_Image.png
2、执行回调第一句,把ul的第一个li挪到最后。这一步完成之后是这样:
Paste_Image.png
也就是说1号li现在已经到队列的最后了,2号li到ul外了,3号li成了可见的排头兵。不过3号成为排头兵也只是一瞬间的辉煌,实际上人眼根本看不到。为什么是一瞬间的辉煌?往下看:
3、执行回调的第二句。将ul的margin-left重置为0。完成之后是这样:
Paste_Image.png
也就是说,ul又挪回到了原位。2号li成了排头兵。
问题:为什么ul挪到原位,没有感到抖动?
答:因为JS执行的太快了,挪动li的排序和给ul还原位置都是几乎同时的,而且是微秒级别的速度。
问题:想让走马灯向右走怎么办?
答:首先说向右走不符合人眼的观察习惯,我们阅读都是从左往右读的,所以向右走的走马灯很少见。一定要向右走的话:
修改CSS:
.content ul li{
float: left; /* 这里left改成right */
}
修改JS:.animate({"margin-left":"-120px"})的负号去掉。
纵向的走马灯
纵向的话,设置每多少个li占一行并没有难度,只需要调整li的宽度即可,一行撑不下自然会折行显示。我们以一行四个li为例。
HTML代码
不变。
CSS代码
有两处修改:
1、把li的宽度改成了960/4-1-1-5-5=228px。(如果你想一个li占一行,li的宽度就应该是960-1-1-5-5=948px。)
2、ul的宽度必须是100%。
.content{
width: 960px;
height:120px;
overflow: hidden;
border: #333 solid 1px;
margin:auto;
}
.content ul{
width: 100%;
height:100%;
margin: 0;
padding: 0;
}
.content ul li{
list-style: none;
float: left;
width: 228px;
height: 108px;
border:#ccc solid 1px;
display: block;
margin: 5px;
}
JS代码
JS代码也是略加改动,除了改成margin-top之外,还有个.slice(0, 4):
function scroll() {
$(".content ul").animate({"margin-top":"-120px"}, function() {
$(".content ul li").slice(0,4).appendTo($(".content ul"));
$(".content ul").css({"margin-top": 0});
});
}
var scrolling = setInterval(scroll, 1000);
$('.content').hover(function() {
clearInterval(scrolling);
}, function() {
scrolling = setInterval(scroll, 1000);
});
问题:我想每两行两行的滚动,怎么办?
答:首先margin-top的值翻倍,然后.slice(0, 4)改成.slice(0, 8)。
问题:咱们这个走马灯是走一步停一下,而常见的走马灯是均匀的走,我想匀速走怎么办?
答:往下看。
匀速走的走马灯
以纵向的走马灯为例。HTML代码和CSS代码都不变。JS代码中animate就加两个参数。
JS代码
function scroll() {
$(".content ul").animate({"margin-top":"-120px"}, 1000, 'linear', function() {
$(".content ul li").slice(0,4).appendTo($(".content ul"));
$(".content ul").css({"margin-top": 0});
});
}
//其他代码略
改动在:.animate()加了两个参数:第一个参数,1000,也就是跟定时器的时间间隔一致,第二个参数,'linear',也就是线性缓动。就这么简单。