横向广告(商品)滚动,做了循环和非循环两种,用的jQuery,效果如下:
非循环的很简单,不做介绍了,说下循环的一些问题:
首先,是HTML的重构,需要在原本的基础上在前后各添加上N个单元,数量为容器显示的数量值。前N个单元复制添加到HTML之后,后N个单元复制添加到HTML之前,形成一个循环的假象。
View Code
var last = lis.detach().slice(lis.length-len).clone(),
first = lis.slice(0,len).clone();
this.maxLeft = (lis.length + len) * width; //最大偏移位置
this.preLeft = len * width; //在HTML之前需要添加的单元宽度
this.left = box.position().left - this.preLeft; //初始实际位置
box.append(lis).prepend(last).append(first).css('left',this.left);
其次,当每次移动到之前额外添加的单元之后,需要对滚动位置做次复位。
View Code
_toPre:function(){
var _this=this;
if(this.isLoop){
this.lock = true;
this.left = this.left + this.boxWidth;
if(this.left < -this.preLeft){
this.box.animate({left:this.left},this.duration,'',function(){
_this.lock=false;
});
}else{
this.box.animate({left:this.left},this.duration,'',function(){
_this.left = _this.left - _this.maxLeft + _this.preLeft;
_this.box.css('left',_this.left);
_this.lock=false;
});
}
}else if(this.left !== 0){
this.lock = true;
this.left = this.left + this.boxWidth;
this.box.animate({left:this.left},this.duration,'',function(){
_this.lock=false;
});
}
},
_toNext:function(){
var _this=this;
if(this.isLoop){
this.lock = true;
this.left = this.left - this.boxWidth;
if(this.left > -this.maxLeft+this.preLeft){
this.box.animate({left:this.left},this.duration,'',function(){
_this.lock=false;
});
}else{
this.box.animate({left:this.left},this.duration,'',function(){
_this.left = _this.left + _this.maxLeft - _this.preLeft;
_this.box.css('left',_this.left);
_this.lock=false;
});
}
}else if(this.left !== -this.maxLeft){
this.lock = true;
this.left = this.left - this.boxWidth;
this.box.animate({left:this.left},this.duration,'',function(){
_this.lock=false;
});
}
}
最后,当鼠标移动到左右按钮及容器范围内时,需要取消自动滚动,以免出现位置错乱情况
View Code
if(this.isLoop && this.isInterval){
this.timer=setInterval(function(){_this._toNext.call(_this)},_this.intervalTime);
this.box.add(this.btnpre).add(this.btnnext).hover(
function(){
clearInterval(_this.timer);
},
function(){
_this.timer=setInterval(function(){_this._toNext.call(_this)},_this.intervalTime);
}
)
}
横向滚动主要是一个位置的判断及控制,理清了这些就很简单
demo下载:listscroll.rar
源代码
1 // JavaScript Document
2 var ListScroll=function(options){
3 this._init(options);
4 if(this.box&&this.len&&this.width){
5 this._setHTML();
6 }
7 }
8 ListScroll.prototype={
9 _init:function(options){
10 this.options={
11 box:null, //容器
12 len:0, //显示数量
13 0, //单位宽度
14 duration:500, //动画持续时间
15 btnpre:null, //向左按钮
16 btnnext:null, //向右按钮
17 isLoop:false, //是否循环
18 isInterval:false, //是否自动
19 intervalTime:4000 //计时器时间
20 }
21 this.options=jQuery.extend(this.options,options||{});
22 this.box=this.options.box;
23 this.len=this.options.len;
24 this.width=this.options.width;
25 this.boxWidth=this.len * this.width;
26 this.duration=this.options.duration;
27 this.btnpre=this.options.btnpre;
28 this.btnnext=this.options.btnnext;
29 this.isLoop=this.options.isLoop;
30 this.isInterval=this.options.isInterval;
31 this.intervalTime=this.options.intervalTime;
32 this.left=0;
33 this.maxLeft=0;
34 this.lock=false;
35 },
36 _setHTML:function(){
37 var box = this.box , len = this.len , width = this.width;
38 var lis = box.children('li');
39 if(lis.length > len){
40 if(this.isLoop){
41 var last = lis.detach().slice(lis.length-len).clone(),
42 first = lis.slice(0,len).clone();
43 this.maxLeft = (lis.length + len) * width;
44 this.preLeft = len * width;
45 this.left = box.position().left - this.preLeft;
46 box.append(lis).prepend(last).append(first).css('left',this.left);
47 }else{
48 this.maxLeft = (Math.ceil(lis.length / len) - 1) * len * width;
49 box.css('left',this.left)
50 }
51 this._bind();
52 }else{
53 this.btnpre.hide();
54 this.btnnext.hide();
55 }
56 },
57 _toPre:function(){
58 var _this=this;
59 if(this.isLoop){
60 this.lock = true;
61 this.left = this.left + this.boxWidth;
62 if(this.left < -this.preLeft){
63 this.box.animate({left:this.left},this.duration,'',function(){
64 _this.lock=false;
65 });
66 }else{
67 this.box.animate({left:this.left},this.duration,'',function(){
68 _this.left = _this.left - _this.maxLeft + _this.preLeft;
69 _this.box.css('left',_this.left);
70 _this.lock=false;
71 });
72 }
73 }else if(this.left !== 0){
74 this.lock = true;
75 this.left = this.left + this.boxWidth;
76 this.box.animate({left:this.left},this.duration,'',function(){
77 _this.lock=false;
78 });
79 }
80
81 },
82 _toNext:function(){
83 var _this=this;
84 if(this.isLoop){
85 this.lock = true;
86 this.left = this.left - this.boxWidth;
87 if(this.left > -this.maxLeft+this.preLeft){
88 this.box.animate({left:this.left},this.duration,'',function(){
89 _this.lock=false;
90 });
91 }else{
92 this.box.animate({left:this.left},this.duration,'',function(){
93 _this.left = _this.left + _this.maxLeft - _this.preLeft;
94 _this.box.css('left',_this.left);
95 _this.lock=false;
96 });
97 }
98 }else if(this.left !== -this.maxLeft){
99 this.lock = true;
100 this.left = this.left - this.boxWidth;
101 this.box.animate({left:this.left},this.duration,'',function(){
102 _this.lock=false;
103 });
104 }
105 },
106 _bind:function(){
107 var _this=this;
108 this.btnpre.click(function(){
109 if(!_this.lock){
110 _this._toPre();
111 }
112 return false;
113 })
114 this.btnnext.click(function(){
115 if(!_this.lock){
116 _this._toNext();
117 }
118 return false;
119 })
120 if(this.isLoop && this.isInterval){
121 this.timer=setInterval(function(){_this._toNext.call(_this)},_this.intervalTime);
122 this.box.add(this.btnpre).add(this.btnnext).hover(
123 function(){
124 clearInterval(_this.timer);
125 },
126 function(){
127 _this.timer=setInterval(function(){_this._toNext.call(_this)},_this.intervalTime);
128 }
129 )
130 }
131 }
132 }
133 $(function(){
134 var listscroll1=new ListScroll({
135 box:$("#scrollul_1"),
136 len:3,
137 280,
138 btnpre:$("#top_pre_1"),
139 btnnext:$("#top_next_1")
140 })
141
142 var listscroll2=new ListScroll({
143 box:$("#scrollul_2"),
144 len:3,
145 280,
146 btnpre:$("#top_pre_2"),
147 btnnext:$("#top_next_2"),
148 isLoop:true,
149 isInterval:true,
150 intervalTime:2000
151 })
152 })