【原创】jQuery插件之图片轮播

周末的时候写了一个图片轮播的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分别是simplecomplex

以下是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!!

欢迎指正错误~~

 

posted @ 2012-12-11 22:56  Lovesueee  阅读(3661)  评论(6编辑  收藏  举报