swipe支持电脑上的自动滑动,也支持手机端的滑动效果.但是每次调用只能支持一个效果或者说一个页面出现n个这样的效果,我们就得调用n次这个插件.
我使用swipe+jQuery使得swip变得方便使用,具有了jQuery插件的有点.只需要一个调用就可以使页面拥有n个这样的效果.
另外在效果中置入了鼠标的点击效果.这个接口是早就给出来了,可是很少在网上看到有人用过这个接口的.
1 <style type="text/css"> 2 #gys img{height:300px;} 3 </style> 4 <div class="gys" id="gys"> 5 <div style="background-color:Red;">第一张</div> 6 <div style="background-color:Green">第二章</div> 7 <div style="background-color:Gray;">第三章</div> 8 <div style="background-color:Red;">第四张</div> 9 <div style="background-color:Green">第五章</div> 10 <div style="background-color:Gray;">第六章</div> 11 </div> 12 <style type="text/css"> 13 #gys2{ margin-top:20px;} 14 #gys2 img{height:300px;} 15 </style> 16 <div class="gys" id="gys2"> 17 <div><img src="1.jpg" style=""/></div> 18 <div><img src="2.jpg" style=""/></div> 19 <div><img src="3.jpg" style=""/></div> 20 <div><img src="4.jpg" style=""/></div> 21 <div><img src="5.jpg" style=""/></div> 22 <div><img src="6.jpg" style=""/></div> 23 </div> 24 25 26 <style type="text/css"> 27 #gys3{ margin-top:20px;} 28 #gys3 > div >div{height:200px;} 29 </style> 30 <div class="gys" id="gys3"> 31 <div style='background:url(1.jpg) center no-repeat;background-size: cover;'><h1>1</h1></div> 32 <div style='background:url(2.jpg) center no-repeat;background-size: cover;'><h1>2</h1></div> 33 <div style='background:url(3.jpg) center no-repeat;background-size: cover;'><h1>3</h1></div> 34 <div style='background:url(4.jpg) center no-repeat;background-size: cover;'><h1>4</h1></div> 35 <div style='background:url(5.jpg) center no-repeat;background-size: cover;'><h1>5</h1></div> 36 <div style='background:url(6.jpg) center no-repeat;background-size: cover;'><h1>6</h1></div> 37 </div>
1 ; (function ($) { 2 var defaults={ 3 "",//幻灯片的宽度 4 startSlide: 2,//Swipe开始的索引 5 speed: 400, //前进和后台的速度,单位毫秒 6 auto: 3000,//自动滑动 7 nav:1,//是否有按钮导航,1.有,2.没有 8 continuous: true, //是否可以循环播放 9 disableScroll: false, //停止触摸滑动 10 }; 11 $.fn.bnWapPPt=function(opt){ 12 opt=$.extend({},defaults,opt); 13 return this.each(function(){ 14 if(!opt.width) 15 opt.width=$(this).parent().width(); 16 var children=$(this).children() 17 var count=children.length; 18 $(this).css({"overflow": "hidden","visibility":"hidden","position":"relative",opt.width+"px"}); 19 children.css({"float":"left","position":"relative","overflow":"hidden","height":"100%"}); 20 children.wrapAll("<div style='overflow: hidden;position: relative;'></div>"); 21 22 23 24 if(opt.nav==1){ 25 var html="<div class='jsSwipeNavBj'><ul class='jsSwipeNav'>"; 26 for(var i=0;i<count;i++){ 27 if(i==opt.startSlide) 28 html+="<li class='on'></li>"; 29 else 30 html+="<li></li>"; 31 } 32 html+="</ul></div>"; 33 $(this).append(html); 34 35 $("ul.jsSwipeNav li",this).click(function(){ 36 $(this).siblings().removeClass("on"); 37 $(this).addClass("on"); 38 SwipeResult.gys($(this).index()); 39 }); 40 41 } 42 var obj=this; 43 if(opt.nav==1){ 44 var navLis=$("ul.jsSwipeNav li",obj); 45 var liWidth=0; 46 navLis.each(function(){ 47 liWidth+=$(this).outerWidth(true); 48 }); 49 $("ul.jsSwipeNav",obj).width(liWidth).css({"overflow":"hidden"}); 50 } 51 52 //通过递归获取底部导航的索引 53 function getIndex(index,n){ 54 if(index>n){ 55 return arguments.callee(index-=count,n); 56 } 57 else { 58 return index; 59 } 60 } 61 62 var navsChange=function (nav){ 63 if(nav==1){ 64 return function(index){ 65 index=getIndex(index,count-1); 66 navLis.removeClass("on").eq(index).addClass("on"); 67 } 68 } 69 else 70 { 71 return function(){} 72 } 73 }(opt.nav); 74 75 var SwipeResult=Swipe($(this).get(0),{ 76 startSlide: opt.startSlide,//Swipe开始的索引 77 speed: opt.speed, //前进和后台的速度,单位毫秒 78 auto: opt.auto,//自动滑动 79 continuous: opt.continuous, //是否可以循环播放 80 disableScroll: opt.disableScroll, //停止触摸滑动 81 stopPropagation: false, //停止事件传播 82 callback: function (index, elem) {//回调函数,可以获取到滑动中图片的索引. 83 navsChange(index); 84 }, 85 transitionEnd: function (index, elem) {//在滑动过渡时执行. 86 } 87 }) 88 }); 89 } 90 91 92 function Swipe(container, options) { 93 "use strict"; 94 var noop = function () { }; // simple no operation function 95 var offloadFn = function (fn) { setTimeout(fn || noop, 0) }; // offload a functions execution 96 var jsLib = window.jQuery || window.Zepto; // jQuery or Zepto 97 98 // check browser capabilities 99 var browser = { 100 addEventListener: !!window.addEventListener, 101 touch: ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch, 102 transitions: (function (temp) { 103 var props = ['transitionProperty', 'WebkitTransition', 'MozTransition', 'OTransition', 'msTransition']; 104 for (var i in props) if (temp.style[props[i]] !== undefined) return true; 105 return false; 106 })(document.createElement('swipe')) 107 }; 108 // quit if no root element 109 if (!container) return; //如果容器为假,不执行 110 var element = container.children[0]; //容器中的第一个子元素(运动区域的元素集合) 111 var slides, slidePos, width, length; 112 options = options || {}; 113 var index = parseInt(options.startSlide, 10) || 0; 114 var speed = options.speed || 300; 115 options.continuous = options.continuous !== undefined ? options.continuous : true; 116 117 function setup() { 118 119 // cache slides 120 slides = element.children; //figure集合 121 length = slides.length; //figure数 122 123 // set continuous to false if only one slide 124 if (slides.length < 2) options.continuous = false; 125 126 //special case if two slides 127 if (browser.transitions && options.continuous && slides.length < 3) { 128 // return; 129 element.appendChild(slides[0].cloneNode(true)); 130 element.appendChild(element.children[1].cloneNode(true)); 131 slides = element.children; 132 } 133 134 // create an array to store current positions of each slide 135 slidePos = new Array(slides.length); 136 137 // determine width of each slide 138 width = container.getBoundingClientRect().width || container.offsetWidth; 139 140 element.style.width = (slides.length * width) + 'px'; 141 142 // stack elements 143 var pos = slides.length; 144 while (pos--) { 145 146 var slide = slides[pos]; 147 148 slide.style.width = width + 'px'; 149 slide.setAttribute('data-index', pos); 150 151 if (browser.transitions) { 152 slide.style.left = (pos * -width) + 'px'; 153 move(pos, index > pos ? -width : (index < pos ? width : 0), 0); 154 } 155 156 } 157 158 // reposition elements before and after index 159 if (options.continuous && browser.transitions) { 160 move(circle(index - 1), -width, 0); 161 move(circle(index + 1), width, 0); 162 } 163 164 if (!browser.transitions) element.style.left = (index * -width) + 'px'; 165 166 container.style.visibility = 'visible'; 167 168 } 169 170 function prev() { 171 172 if (options.continuous) slide(index - 1); 173 else if (index) slide(index - 1); 174 175 } 176 177 function next() { 178 179 if (options.continuous) slide(index + 1); 180 else if (index < slides.length - 1) slide(index + 1); 181 182 } 183 184 function circle(index) { 185 186 // a simple positive modulo using slides.length 187 return (slides.length + (index % slides.length)) % slides.length; 188 189 } 190 function gys(container, options,gysIndex){ 191 options=$.extend(options,gysIndex); 192 Swipe(container, options); 193 } 194 function slide(to, slideSpeed) { 195 196 // do nothing if already on requested slide 197 if (index == to) return; 198 199 if (browser.transitions) { 200 201 var direction = Math.abs(index - to) / (index - to); // 1: backward, -1: forward 202 203 // get the actual position of the slide 204 if (options.continuous) { 205 var natural_direction = direction; 206 direction = -slidePos[circle(to)] / width; 207 208 // if going forward but to < index, use to = slides.length + to 209 // if going backward but to > index, use to = -slides.length + to 210 if (direction !== natural_direction) to = -direction * slides.length + to; 211 212 } 213 214 var diff = Math.abs(index - to) - 1; 215 216 // move all the slides between index and to in the right direction 217 while (diff--) move(circle((to > index ? to : index) - diff - 1), width * direction, 0); 218 219 to = circle(to); 220 221 move(index, width * direction, slideSpeed || speed); 222 move(to, 0, slideSpeed || speed); 223 224 if (options.continuous) move(circle(to - direction), -(width * direction), 0); // we need to get the next in place 225 226 } else { 227 228 to = circle(to); 229 animate(index * -width, to * -width, slideSpeed || speed); 230 //no fallback for a circular continuous if the browser does not accept transitions 231 } 232 233 index = to; 234 offloadFn(options.callback && options.callback(index, slides[index])); 235 } 236 237 function move(index, dist, speed) { 238 239 translate(index, dist, speed); 240 slidePos[index] = dist; 241 242 } 243 244 function translate(index, dist, speed) { 245 246 var slide = slides[index]; 247 var style = slide && slide.style; 248 249 if (!style) return; 250 251 style.webkitTransitionDuration = 252 style.MozTransitionDuration = 253 style.msTransitionDuration = 254 style.OTransitionDuration = 255 style.transitionDuration = speed + 'ms'; 256 257 style.webkitTransform = 'translate(' + dist + 'px,0)' + 'translateZ(0)'; 258 style.msTransform = 259 style.MozTransform = 260 style.OTransform = 'translateX(' + dist + 'px)'; 261 262 } 263 264 function animate(from, to, speed) { 265 266 // if not an animation, just reposition 267 if (!speed) { 268 269 element.style.left = to + 'px'; 270 return; 271 272 } 273 274 var start = +new Date; 275 276 var timer = setInterval(function () { 277 278 var timeElap = +new Date - start; 279 280 if (timeElap > speed) { 281 282 element.style.left = to + 'px'; 283 284 if (delay) begin(); 285 286 options.transitionEnd && options.transitionEnd.call(event, index, slides[index]); 287 288 clearInterval(timer); 289 return; 290 291 } 292 293 element.style.left = (((to - from) * (Math.floor((timeElap / speed) * 100) / 100)) + from) + 'px'; 294 295 }, 4); 296 297 } 298 299 // setup auto slideshow 300 var delay = options.auto || 0; 301 var interval; 302 303 function begin() { 304 305 interval = setTimeout(next, delay); 306 307 } 308 309 function stop() { 310 311 delay = 0; 312 clearTimeout(interval); 313 314 } 315 316 317 // setup initial vars 318 var start = {}; 319 var delta = {}; 320 var isScrolling; 321 322 // setup event capturing 323 var events = { 324 325 handleEvent: function (event) { 326 327 switch (event.type) { 328 case 'touchstart': this.start(event); break; 329 case 'touchmove': this.move(event); break; 330 case 'touchend': offloadFn(this.end(event)); break; 331 case 'webkitTransitionEnd': 332 case 'msTransitionEnd': 333 case 'oTransitionEnd': 334 case 'otransitionend': 335 case 'transitionend': offloadFn(this.transitionEnd(event)); break; 336 case 'resize': offloadFn(setup); break; 337 } 338 339 if (options.stopPropagation) event.stopPropagation(); 340 341 }, 342 start: function (event) { 343 344 var touches = event.touches[0]; 345 346 // measure start values 347 start = { 348 349 // get initial touch coords 350 x: touches.pageX, 351 y: touches.pageY, 352 353 // store time to determine touch duration 354 time: +new Date 355 356 }; 357 358 // used for testing first move event 359 isScrolling = undefined; 360 361 // reset delta and end measurements 362 delta = {}; 363 364 // attach touchmove and touchend listeners 365 element.addEventListener('touchmove', this, false); 366 element.addEventListener('touchend', this, false); 367 368 }, 369 move: function (event) { 370 371 // ensure swiping with one touch and not pinching 372 if (event.touches.length > 1 || event.scale && event.scale !== 1) return 373 374 if (options.disableScroll) event.preventDefault(); 375 376 var touches = event.touches[0]; 377 378 // measure change in x and y 379 delta = { 380 x: touches.pageX - start.x, 381 y: touches.pageY - start.y 382 } 383 384 // determine if scrolling test has run - one time test 385 if (typeof isScrolling == 'undefined') { 386 isScrolling = !!(isScrolling || Math.abs(delta.x) < Math.abs(delta.y)); 387 } 388 389 // if user is not trying to scroll vertically 390 if (!isScrolling) { 391 392 // prevent native scrolling 393 event.preventDefault(); 394 395 // stop slideshow 396 stop(); 397 398 // increase resistance if first or last slide 399 if (options.continuous) { // we don't add resistance at the end 400 401 translate(circle(index - 1), delta.x + slidePos[circle(index - 1)], 0); 402 translate(index, delta.x + slidePos[index], 0); 403 translate(circle(index + 1), delta.x + slidePos[circle(index + 1)], 0); 404 405 } else { 406 407 delta.x = 408 delta.x / 409 ((!index && delta.x > 0 // if first slide and sliding left 410 || index == slides.length - 1 // or if last slide and sliding right 411 && delta.x < 0 // and if sliding at all 412 ) ? 413 (Math.abs(delta.x) / width + 1) // determine resistance level 414 : 1); // no resistance if false 415 416 // translate 1:1 417 translate(index - 1, delta.x + slidePos[index - 1], 0); 418 translate(index, delta.x + slidePos[index], 0); 419 translate(index + 1, delta.x + slidePos[index + 1], 0); 420 } 421 422 } 423 424 }, 425 end: function (event) { 426 427 // measure duration 428 var duration = +new Date - start.time; 429 430 // determine if slide attempt triggers next/prev slide 431 var isValidSlide = 432 Number(duration) < 250 // if slide duration is less than 250ms 433 && Math.abs(delta.x) > 20 // and if slide amt is greater than 20px 434 || Math.abs(delta.x) > width / 2; // or if slide amt is greater than half the width 435 436 // determine if slide attempt is past start and end 437 var isPastBounds = 438 !index && delta.x > 0 // if first slide and slide amt is greater than 0 439 || index == slides.length - 1 && delta.x < 0; // or if last slide and slide amt is less than 0 440 441 if (options.continuous) isPastBounds = false; 442 443 // determine direction of swipe (true:right, false:left) 444 var direction = delta.x < 0; 445 446 // if not scrolling vertically 447 if (!isScrolling) { 448 449 if (isValidSlide && !isPastBounds) { 450 451 if (direction) { 452 453 if (options.continuous) { // we need to get the next in this direction in place 454 455 move(circle(index - 1), -width, 0); 456 move(circle(index + 2), width, 0); 457 458 } else { 459 move(index - 1, -width, 0); 460 } 461 462 move(index, slidePos[index] - width, speed); 463 move(circle(index + 1), slidePos[circle(index + 1)] - width, speed); 464 index = circle(index + 1); 465 466 } else { 467 if (options.continuous) { // we need to get the next in this direction in place 468 469 move(circle(index + 1), width, 0); 470 move(circle(index - 2), -width, 0); 471 472 } else { 473 move(index + 1, width, 0); 474 } 475 476 move(index, slidePos[index] + width, speed); 477 move(circle(index - 1), slidePos[circle(index - 1)] + width, speed); 478 index = circle(index - 1); 479 480 } 481 482 options.callback && options.callback(index, slides[index]); 483 484 } else { 485 486 if (options.continuous) { 487 488 move(circle(index - 1), -width, speed); 489 move(index, 0, speed); 490 move(circle(index + 1), width, speed); 491 492 } else { 493 494 move(index - 1, -width, speed); 495 move(index, 0, speed); 496 move(index + 1, width, speed); 497 } 498 499 } 500 501 } 502 503 // kill touchmove and touchend event listeners until touchstart called again 504 element.removeEventListener('touchmove', events, false) 505 element.removeEventListener('touchend', events, false) 506 507 }, 508 transitionEnd: function (event) { 509 510 if (parseInt(event.target.getAttribute('data-index'), 10) == index) { 511 512 if (delay) begin(); 513 514 options.transitionEnd && options.transitionEnd.call(event, index, slides[index]); 515 516 } 517 518 } 519 520 } 521 522 // trigger setup 523 setup(); 524 525 // start auto slideshow if applicable 526 if (delay) begin(); 527 528 529 // add event listeners 530 if (browser.addEventListener) { 531 532 // set touchstart event on element 533 if (browser.touch) element.addEventListener('touchstart', events, false); 534 535 if (browser.transitions) { 536 element.addEventListener('webkitTransitionEnd', events, false); 537 element.addEventListener('msTransitionEnd', events, false); 538 element.addEventListener('oTransitionEnd', events, false); 539 element.addEventListener('otransitionend', events, false); 540 element.addEventListener('transitionend', events, false); 541 } 542 543 // set resize event on window 544 window.addEventListener('resize', events, false); 545 546 } else { 547 548 window.onresize = function () { setup() }; // to play nice with old IE 549 550 } 551 552 // expose the Swipe API 553 return { 554 setup: function () { 555 556 setup(); 557 558 }, 559 gys:function(to){ 560 stop(); 561 gys(container, options,{startSlide:to}); 562 }, 563 slide: function (to, speed) { 564 stop(); 565 slide(to, speed); 566 }, 567 prev: function () { 568 569 // cancel slideshow 570 stop(); 571 572 prev(); 573 574 }, 575 next: function () { 576 577 // cancel slideshow 578 stop(); 579 580 next(); 581 582 }, 583 stop: function () { 584 585 // cancel slideshow 586 stop(); 587 588 }, 589 getPos: function () { 590 591 // return current index position 592 return index; 593 594 }, 595 getNumSlides: function () { 596 597 // return total number of slides 598 return length; 599 }, 600 kill: function () { 601 602 // cancel slideshow 603 stop(); 604 605 // reset element 606 element.style.width = 'auto'; 607 element.style.left = 0; 608 609 // reset slides 610 var pos = slides.length; 611 while (pos--) { 612 613 var slide = slides[pos]; 614 slide.style.width = '100%'; 615 slide.style.left = 0; 616 617 if (browser.transitions) translate(pos, 0, 0); 618 619 } 620 621 // removed event listeners 622 if (browser.addEventListener) { 623 624 // remove current event listeners 625 element.removeEventListener('touchstart', events, false); 626 element.removeEventListener('webkitTransitionEnd', events, false); 627 element.removeEventListener('msTransitionEnd', events, false); 628 element.removeEventListener('oTransitionEnd', events, false); 629 element.removeEventListener('otransitionend', events, false); 630 element.removeEventListener('transitionend', events, false); 631 window.removeEventListener('resize', events, false); 632 } 633 else { 634 635 window.onresize = null; 636 637 } 638 639 } 640 } 641 642 } 643 })(jQuery);
调用:
1 $(function(){ 2 $(".gys").bnWapPPt({ 3 500,//幻灯片宽度 4 startSlide: 1,//Swipe开始的索引 5 speed: 400, //滑动的速度,单位毫秒 6 auto: 3000,//自动滑动之间的间隔时间 7 nav:1,//是否有底部原点的导航.1表示有,其他任何值表示没有 8 continuous: true, //是否可以循环播放 9 disableScroll: false //停止触摸滑动 10 }); 11 })