【原创】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分别是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!!
欢迎指正错误~~
分类:
plugin
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!