周末的时候写了一个图片轮播的jQuery插件,今天应产品的需求,又改进了些,所以写了两个版本slideshow.js和slideshow_v2.js;
代码中提供两个接口:
1. jQuery接口
2. CMD接口(相当于返回一个构造器),对外暴露包装后的public api(下面功能中说到)
那么实现的功能:
1,基本的的轮播功能:向前(prev),向后(next),第一张(first),最后一张(last),指定图片索引(jumpto),向前(后)自动播放(play),停止播放(stop)
2. 关于图片的请求做了一些处理,每一个slideshow的大小都是通过参数自定义生成的,那么对于大量图片数据,处理的方式是这样的:
根据slideshow的实际宽度,算出并展示可视区域缩略图的个数,当点击至最后一个已下载缩略图时,才会下载另一批缩略图,并生成相应的dom。
同样的,对于预览图(中图),也是点击缩略图后才会进行请求。
3. 在视觉上做的是缩略图滚动,使选中的图片剧中显示。
效果图:
上面介绍的是第一个版本slideshow.js,在slideshow_v2.js上又有少许的改动,主要是在事件支持上:
1. 给缩略图添加mouseenter事件,减少用户使用成本(产品如是说)
2. 当鼠标放在左右箭头时,开始自动播放,移开停止自动播放,同样是为了减少用户适用成本(产品如是说)
针对slideshow.js和slideshow_v2.js,给出了两个demo分别是simple和complex。
以下是slideshow.js的源代码:
1 /**
2 * @description 图片轮播jQuery插件
3 * @file slideshow.js
4 * @dep jquery
5 * @author lovesueee@me.com
6 * @version 2012-12-06
7 */
8
9 define(['./slideshow.css'],function (require, exports, module) {
10
11 var $ = require('./jquery.js');
12
13 // Slide默认配置
14 var SlideConfig = {
15
16 start : 0, // 起始图片的索引,从0开始
17
18 interval : 0, // 自动轮播的时间间隔,如果为0,表示不自动轮播,单位为秒
19
20 repeat : true, // 是否循环重复轮播
21
22 width : 302, // 组件宽度,如果为0,表示自由宽度
23
24 viewHeight : 200, // view视图高度
25
26 navHeight : 53, // navgation导航条高度
27
28 arrWidth : 8, // 导航箭头的宽度
29
30 arrHeight : 20, // 导航箭头的高度
31
32
33 thumbWidth : 54, // 缩略图的宽度
34
35 data : { // 图片数据
36
37 sImgs : [], // 小图
38 mImgs : [], // 中图
39 bImgs : [] // 大图
40 }
41
42 };
43
44 var SlideShow = function (options) {
45
46 var $el;
47
48 $el = options.$el;
49
50 if ($el.length === 0) return;
51
52 if ($el.length > 1) {
53
54 $el.each(function () {
55 $(this).slideShow(options);
56 });
57
58 return;
59 }
60
61 this.$el = $el;
62
63 this.config = $.extend({}, SlideConfig, options);
64
65 this.init();
66
67 };
68
69 SlideShow.prototype = {
70
71 constructor : SlideShow,
72
73 init : function () {
74
75 var $el = this.$el;
76
77 var config = this.config;
78
79 var data = config.data
80
81 var number = Math.min(data.sImgs.length, data.mImgs.length, data.bImgs.length);
82
83 if (number === 0) throw new Error('number of images is zero');
84
85 this.number = number;
86
87 var current = config.start % number;
88
89 this.current = -1;
90
91 this.length = 0;
92
93 var width = config.width;
94
95 width !== 0 && $el.css('width', width);
96
97 $el.addClass('gj-slide-show').css('visibility', 'hidden');
98
99 this.createDom();
100
101 this.jumpto(current);
102
103 config.interval > 0 && this.play();
104
105 $el.css('visibility', 'visible');
106
107 return this;
108
109 },
110
111 createDom : function () {
112
113 var $el = this.$el;
114
115 var config = this.config;
116
117 var $view = $('<div></div>');
118
119 var $a = $('<a></a>');
120
121 var $img = $('<img>');
122
123
124 $a.attr({
125 title : '查看大图',
126 href : '#',
127 target : '_blank'
128 }).append($img);
129
130 $view.append($a)
131 .addClass('gj-slide-view')
132 .css('height', config.viewHeight);
133
134
135
136 var navHeight = config.navHeight;
137
138 var arrWidth = config.arrWidth;
139
140 var arrHeight = config.arrHeight;
141
142 var top = Math.round((config.navHeight - 14) / 2 - arrHeight / 2);
143
144 var $nav = $('<div></div>');
145
146 var $larr = $('<div></div>');
147
148 var $rarr = $('<div></div>');
149
150 var $thumbs = $('<div></div>');
151
152 var $ul = $('<ul></ul>');
153
154 var $la = $('<a></a>');
155
156 var $ra = $('<a></a>');
157
158 $la.attr('href', '#')
159 .css({
160 height : arrHeight,
161 width : arrWidth,
162 top : top
163 });
164
165 $larr.append($la)
166 .addClass('gj-slide-forward gj-slide-arrow')
167 .css('width', arrWidth);
168
169 $ra.attr('href', '#')
170 .css({
171 height : arrHeight,
172 width : arrWidth,
173 top : top
174 });
175
176 $rarr.append($ra)
177 .addClass('gj-slide-backward gj-slide-arrow')
178 .css('width', arrWidth);
179
180 $ul.addClass('clear')
181 .css('width', (config.thumbWidth + 17) * this.number);
182
183 $thumbs.append($ul)
184 .addClass('gj-slide-thumbs')
185 .css({
186 width : config.width - 2 * arrWidth - 9,
187 height : navHeight
188 });
189
190 $nav.append($larr)
191 .append($thumbs)
192 .append($rarr)
193 .addClass('gj-slide-nav clear')
194 .css('height', navHeight);
195
196 $el.append($view).append($nav);
197
198
199 var me = this;
200
201 $la.on('click', function () {
202
203 me.prev();
204
205 return false;
206 });
207
208 $ra.on('click', function () {
209
210 me.next();
211
212 return false;
213 });
214
215 this.$ul = $ul;
216 this.$img = $img;
217 this.$a = $a;
218
219 // 可视缩略图个数
220 var visnum = this.visnum = Math.round($thumbs.width() / (config.thumbWidth + 16));
221 // 缩略图移动的步数
222 this.steps = 0;
223 // 最大移动步数
224 var maxsteps = this.maxsteps = this.number - visnum + 1;
225 maxsteps < 0 && (this.maxsteps = 0);
226 // 中间缩略图索引
227 this.midIndex = Math.floor(visnum / 2);
228
229 return this;
230 },
231
232 loadThumbs : function (num) {
233
234 var sIndex, length;
235
236 sIndex = length = this.length;
237
238 var number = this.number;
239
240 var config = this.config;
241
242 (!num || num < this.visnum) && (num = this.visnum);
243
244 var rest = number - length;
245
246 num > rest && (num = rest);
247
248 if (num === 0) return this;;
249
250 var $ul = this.$ul;
251
252 var data = config.data;
253
254 var lIndex = sIndex + num;
255
256 var me = this;
257
258 for (var i = sIndex; i < lIndex; i++) {
259
260 var $li = $('<li></li>');
261
262 var $a = $('<a></a>');
263
264 var $img = $('<img>');
265
266 $img.attr('src', data.sImgs[i])
267 .css({
268 width : config.thumbWidth,
269 height : config.navHeight - 14
270 });
271
272 $a.attr('href', '#')
273 .append($img);
274
275 $li.addClass('gj-slide-thumb')
276 .attr('gj-side-index', i)
277 .append($a);
278
279 $ul.append($li);
280
281 $li.on('click', function () {
282
283 me.jumpto($(this).attr('gj-side-index'));
284
285 return false;
286
287 });
288
289 this[i] = $li;
290 }
291
292 this.length = length + num;
293
294 return this;
295
296 },
297
298 play : function (interval) {
299
300 var config = this.config;
301
302 if (interval) {
303
304 this.config.interval = interval;
305
306 } else {
307
308 interval = config.interval;
309 }
310
311 if (!interval) return this;
312
313 var me = this;
314
315 this.interval && this.stop();
316
317 this.interval = window.setInterval(function () {
318
319 me.next();
320
321 }, interval * 1000);
322
323 return this;
324 },
325
326 stop : function () {
327
328 if (this.interval) {
329 window.clearInterval(this.interval);
330 delete this.interval;
331 }
332
333 return this;
334 },
335
336 prev : function () {
337
338 this.jumpto(this.current - 1);
339
340 return this;
341
342 },
343
344 next : function () {
345
346 this.jumpto(this.current + 1);
347
348 return this;
349 },
350
351 first : function () {
352
353 this.jumpto(0);
354
355 return this;
356 },
357
358 last : function () {
359
360 this.jumpto(this.length - 1);
361
362 return this;
363 },
364
365 jumpto : function (index) {
366
367 var length = this.length;
368
369 var number = this.number;
370
371 var config = this.config;
372
373 var data = config. data;
374
375 // 是否循环重复轮播
376 if (!config.repeat) {
377
378 index < 0 && (index = 0);
379
380 index >= number && (index = number -1);
381
382 (index === 0 || index === number - 1) && this.interval && this.stop();
383
384 } else {
385
386 index = index % number;
387
388 index < 0 && (index += number);
389
390 }
391
392 var num = index - length + 1;
393
394 num > 0 && this.loadThumbs(num);
395
396 var lastIndex = this.current;
397
398 if (lastIndex === index) return this;
399
400 this.current = index;
401
402 var maxsteps = this.maxsteps;
403 var steps = index - this.midIndex + this.steps;
404 var step = 0;
405
406 if (steps < 0) {
407 step = steps;
408 steps = 0;
409 }
410
411 if (steps > maxsteps) {
412 step = steps - maxsteps;
413 steps = maxsteps;
414 }
415
416 if (steps !== this.steps) {
417
418 this.$ul.animate({
419 left : -steps * (config.thumbWidth + 16)
420 });
421
422 this.midIndex = index - step;
423 steps > this.steps && (index + 1) % this.visnum === 0 && this.loadThumbs();
424 this.steps = steps;
425 }
426
427 var lastEl = this[lastIndex];
428
429 lastEl && lastEl.removeClass('select');
430
431 this[index].addClass('select');
432
433 this.$img.attr('src', data.mImgs[index]);
434 this.$a.attr('href', data.bImgs[index]);
435
436 return this;
437 }
438 };
439
440 // jQuery接口
441 $.fn.slideShow = function (options) {
442
443 !options && (options = {});
444
445 options.$el = this;
446
447 new SlideShow(options);
448
449 return this;
450 };
451
452 // CMD接口
453 return function (options) {
454
455 var el, $el;
456
457 if (!options || !(el = options.el)) throw new Error('options.el is needed');
458
459 $el = (el instanceof $) ? el : $(el);
460
461 // 只对第一个元素进行处理
462 options.$el = $el.length > 1 ? $($el[0]) : $el;
463
464 var slide = new SlideShow(options);
465
466 // 公开API
467 return {
468
469 prev : slide.prev,
470
471 next : slide.next,
472
473 first : slide.first,
474
475 last : slide.last,
476
477 jumpto : slide.jumpto,
478
479 play : slide.play,
480
481 stop : slide.stop
482
483 };
484 };
485 });
over!!
欢迎指正错误~~