根本不用插件,实现jQuery横/纵向走马灯

走马灯这么基础的效果,没必要动用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。完成之后是这样:

根本不用插件,实现jQuery横/纵向走马灯_第1张图片
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',也就是线性缓动。就这么简单。

你可能感兴趣的:(根本不用插件,实现jQuery横/纵向走马灯)