支持觸屏的jQuery輪播圖插件

移動輪播圖我看到兩類,javascript

一款是無線天貓的m.tmall.com和攜程,實現了無縫輪播。css

一款是蘑菇街的,沒有實現無縫輪播。html

我本身重寫一個,相似天貓。html5

1.頁面代碼java

 1 <!DOCTYPE html>
 2 <html xmlns="http://www.w3.org/1999/xhtml" lang="UTF-8">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>基於jQuery的移動輪播圖(支持觸屏)</title>
 6     <meta name="viewport" content="maximum-scale=1,initial-scale=1,user-scalable=0">
 7 
 8     <style type="text/css">
 9 
10     img
11     {
12         border:0;
13         *display:inline;
14     }
15     li
16 {
17     border:0;
18     list-style-type :none;  
19 }
20 ul
21 {
22     list-style:none;
23     margin:0;
24     padding:0;
25 }
26     body{
27         overflow-x:hidden;
28         margin:0 auto;
29         padding:0;
30         width: 100%;
31         height: 100%;
32     }
33     .WSCSlideWrapper{
34         width:100%;
35         position: relative;
36         margin:0 auto;
37         //cursor:move;
38     }
39     #WSCSlideWrapperTwo{
40         width:50%;
41         position: relative;
42         margin:10px auto;
43         //cursor:move;
44     }
45     
46     </style>
47     <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/jquery-1.8.2.min.js"></script>
48 
49     <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/touchslide-1.1.js"></script>
50 </head>
51 <body>
52 
53     
54     <div class="WSCSlideWrapper" id="WSCSlideWrapper" >
55     
56         <div>
57         
58             <a  href="http://www.baidu.com"><img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/1.jpg" /></a>
59       <a  href="http://m.tmall.com"><img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/2.jpg" /></a>
60      <a href="http://huaban.com"><img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/3.jpg" /></a>            
61        </div>
62    
63     </div>
64 
65      <div class="WSCSlideWrapper" id="WSCSlideWrapperTwo" >
66         <div>
67              <a><img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/1 (1).jpg" /></a> 
68              <a><img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/1 (2).jpg" /></a>    
69              <a><img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/1 (3).jpg" /></a> 
70              <a><img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/1 (4).jpg" /></a>             
71         </div>
72       
73     </div>
74 <script type="text/javascript">
75  
76 $(document).ready(function(){
77 
78     $('.WSCSlideWrapper').height($('.WSCSlideWrapper').width()*0.3);
79     $('#WSCSlideWrapperTwo').height($('#WSCSlideWrapperTwo').width()*1.5);
80     $('.WSCSlideWrapper').touchslide({timecontrol:3000,animatetime:300,direction:'left',navshow:true,canvassuport:true});
81 });
82 
83     
84 </script>
85 </body>
86 </html>
View Code

2.js插件代碼jquery

  1 /* 
  2 * touchslide 1.1 
  3 * Copyright (c) 2014 BowenLuo http://www.luobo.com/ 
  4 * Date: 2014-06-08
  5 * Example:$('.WSCSlideWrapper').touchslide({timecontrol:3000,animatetime:300,direction:'left',navshow:true,canvassuport:true});
  6 * Update:增長對IE9+等非Safari內核瀏覽器的鼠標拖動圖片功能
  7 */ 
  8 (function($){ 
  9 $.fn.touchslide = function(options){ 
 10 var defaults = { 
 11     timecontrol:3000,//圖片停留時間
 12     animatetime:300, //圖片滑動所需時間
 13     direction:'left', //輪播方向
 14     navshow:true,//是否顯示圖片導航欄
 15     canvassuport:true//圖片導航欄是否開啓cavas繪製圓
 16 } 
 17 var options = $.extend(defaults, options); 
 18 var timecontrol = options.timecontrol||3000;
 19 var animatetime = options.animatetime||300;
 20 var direction = options.direction||'left';
 21 var navshow = options.navshow;
 22 this.each(function(){ 
 23     var slideWrapper=$(this);
 24     var slideImgWrapper = slideWrapper.children('div:first');
 25     var slideAs = slideImgWrapper.children('a');
 26     var slideImgs = slideAs.children('img');
 27     var imgcount = slideImgs.length;
 28     var imgcountrealy = slideImgs.length;
 29     var navimgs;
 30     var circlewrapper;
 31     var circles;
 32     var canvassuport = true;
 33     var circler = 0;
 34     if(imgcount>1){
 35         $((slideImgWrapper.html().split("/a>")[0]+"/a>"+slideImgWrapper.html().split("/a>")[1]+"/a>")).insertAfter(slideAs.last());
 36         if(navshow){
 37             $("<div class='navimgs'></div>").insertAfter(slideImgWrapper);
 38             navimgs = slideWrapper.children('div:last');
 39             navimgs.append("<div class='circlewrapper'></div>");
 40             circlewrapper = navimgs.children('div:first');
 41             for(var i=0;i<imgcountrealy;i++){
 42                 circlewrapper.append("<canvas class='circle' width='15' height='15'></canvas>");
 43             }
 44             circles = circlewrapper.children('canvas');
 45             var myCanvas = circles[1];
 46             if (!myCanvas.getContext) 
 47             { 
 48                 canvassuport =false;
 49             }else 
 50             { 
 51                 canvassuport =options.canvassuport;            
 52             }         
 53         }
 54     }    
 55     slideAs =  slideImgWrapper.children('a');
 56     slideImgs = slideAs.children('img');    
 57     imgcount = slideImgs.length;
 58     var slideWrapperWidth = slideWrapper.width();    
 59     var slideWrapperHeight = slideWrapper.height();
 60     slideWrapper.css({"overflow":"hidden","width":slideWrapperWidth,"height":slideWrapperHeight});
 61     slideImgWrapper.css({'position':"absolute","z-index":"1","overflow":"hidden","width":slideWrapperWidth*imgcount,"height":slideWrapperHeight});    
 62     slideAs.css({'position':"relative","overflow":"hidden","float":"left","width":slideWrapperWidth,"height":slideWrapperHeight});    
 63     slideImgs.css({'position':"relative","z-index":"1","width":slideWrapperWidth,"height":slideWrapperHeight});
 64     if(typeof(navimgs)!=='undefined'){
 65         if(navshow){
 66         navimgs.css({"position":"absolute","z-index":"3","overflow":"hidden","display":"block","width":slideWrapperWidth,"height":slideWrapperWidth*0.05,"bottom":"0"});
 67         if(slideWrapperWidth*0.05>15){
 68             navimgs.height(24);
 69         }
 70         circlewrapper.css({"position":"relative","overflow":"hidden","width":(slideWrapperWidth*0.05*imgcountrealy),"height":slideWrapperWidth*0.04,"margin":"auto"});        
 71         circles.css({'position':"relative","float":"left","max-width":15,"max-height":15,"margin-left":slideWrapperWidth*0.01});
 72         if(slideWrapperWidth*0.03>15){
 73             circler=15;
 74         }else{
 75             circler = slideWrapperWidth*0.03;
 76         }                
 77         circles.attr("width",circler);
 78         circles.attr("height",circler);
 79         canvacircle(0);        
 80         for(var i=0;i<circles.length;i++){
 81             navclick(i);
 82         }    
 83         }else{
 84             navimgs.css({"display":"none"});
 85         }
 86     }        
 87     if(imgcount<4){
 88         return;
 89     }
 90     slideImgWrapper.css({'left':-slideWrapperWidth});
 91     var st;
 92     var sts;
 93     sts = setTimeout(function(){
 94         timedCount();
 95     },timecontrol);    
 96     
 97     slideWrapper.hover(function(){
 98             stopAll();
 99         },
100         function(){
101         sts = setTimeout(function(){
102             timedCount();
103         },timecontrol);
104     });
105     mouseDrag(slideWrapper);
106     touchDrag(slideWrapper);
107         
108     function timedCount()
109     {
110         if(direction=='left'){
111             turnleft();
112         }if(direction=='right'){
113             turnright();
114         }        
115         clearTimeout(st);
116         st=setTimeout(function(){
117             timedCount();        
118         },timecontrol);
119     }
120 
121     function stopCount()
122     {
123         if (st !=""){
124             clearTimeout(st);
125         }
126     }
127     
128     function stopAll()
129     {
130         stopCount();
131         clearTimeout(sts);
132         slideImgWrapper.stop(true);
133     }
134     
135     function navclick(navnum){
136         circlewrapper.children('canvas:eq('+navnum+')').click(function(e){
137                 scideimgskip(navnum+1);
138         })
139     }
140     
141     function scideimgskip(imgnum){
142         stopAll();
143         turnleftwidth = imgnum*slideWrapperWidth;
144         slideImgWrapper.stop(true).animate({left:-turnleftwidth},animatetime,function(){
145             var imgnum = turnleftwidth/slideWrapperWidth-1;
146             if(imgnum==0){
147                 imgnum=imgcountrealy;
148             }
149             if((imgnum-imgcountrealy)==0){
150                 imgnum=0;
151             }
152             canvacircle(imgnum);
153         });    
154     }
155     
156     function canvacircle(canvanum){
157         circles.attr("width",circler);
158         circles.attr("height",circler);
159         for(var i=0;i<circles.length;i++){
160             if(canvassuport){
161                 var navCanvas=circles[i];
162                 var cxt=navCanvas.getContext("2d");
163                 if(i==canvanum){
164                     cxt.fillStyle="#0182D7";    
165                 }else{
166                     cxt.fillStyle="#ddd";    
167                 }                
168                 cxt.arc(circler*0.5,circler*0.5,circler*0.5,0,Math.PI*2,true);
169                 cxt.closePath();
170                 cxt.fill(); 
171             }else{
172                 circles.css("background","#ddd");                
173                 circlewrapper.children('canvas:eq('+canvanum+')').css("background","#0182D7");                
174             }
175             
176         }
177     }
178     
179     var turnleftwidth = slideWrapperWidth;
180     function turnleft(){
181         turnleftwidth = turnleftwidth+slideWrapperWidth;    
182         if(turnleftwidth>(imgcount-2)*slideWrapperWidth){        
183             slideImgWrapper.css({'left':0});
184             turnleftwidth = slideWrapperWidth;
185         }
186         slideImgWrapper.stop(true).animate({left:-turnleftwidth},animatetime,function(){
187             var imgnum = turnleftwidth/slideWrapperWidth-1;
188             if(imgnum==0){
189                 imgnum=imgcountrealy;
190             }
191             if((imgnum-imgcountrealy)==0){
192                 imgnum=0;
193             }
194             canvacircle(imgnum);
195         });                
196     }
197     function turnright(){     
198         turnleftwidth = turnleftwidth-slideWrapperWidth;    
199         if(turnleftwidth==0){        
200             slideImgWrapper.css({'left':-slideWrapperWidth*(imgcount-1)});
201             turnleftwidth = slideWrapperWidth*(imgcount-2);
202         }
203         slideImgWrapper.stop(true).animate({left:-turnleftwidth},animatetime,function(){
204             var imgnum = turnleftwidth/slideWrapperWidth-1;
205             if(imgnum==0){
206                 imgnum=imgcountrealy;
207             }
208             if((imgnum-imgcountrealy)==0){
209                 imgnum=0;
210             }
211             canvacircle(imgnum);
212         });                
213     }
214     
215     var distanceX=0;        
216         
217     function toLeft(){
218         if(turnleftwidth>(imgcount-3)*slideWrapperWidth){
219             slideImgWrapper.css({"left":distanceX});
220                 turnleftwidth = 0;
221             }
222         turnleft(); 
223         sts = setTimeout(function(){
224             timedCount();
225         },timecontrol);    
226     }    
227     
228     function toRight(){
229         if(turnleftwidth==slideWrapperWidth){
230             slideImgWrapper.css({'left':-slideWrapperWidth*(imgcount-1)+distanceX});
231             turnleftwidth = slideWrapperWidth*(imgcount-1);
232         }
233         turnright();    
234         sts = setTimeout(function(){
235             timedCount();
236         },timecontrol);        
237     }
238         
239     function mouseDrag($element) {
240         var eventEle = $element;
241         var stx = etx = curX = 0;
242         var MAction = false;
243         var ahrefs = [];        
244         for(var i=0;i<slideAs.length;i++){
245             if(typeof(slideImgWrapper.children('a:eq('+i+')').attr('href'))!=='undefined'){
246                 ahrefs.push(slideImgWrapper.children('a:eq('+i+')').attr('href'));
247             }        
248         }        
249         eventEle.mouseover(function(){
250             for(var i=0;i<slideAs.length;i++){
251                 if(typeof(slideImgWrapper.children('a:eq('+i+')').attr('href'))!=='undefined'){
252                     slideImgWrapper.children('a:eq('+i+')').attr('href',ahrefs[i]);
253                 }        
254             }
255         });
256         eventEle.mousemove(function(event){            
257             if(MAction){
258             var changeX = event.pageX-stx;    
259             slideImgWrapper.css({"left":-turnleftwidth+changeX});
260             distanceX = changeX;
261             }
262              event.preventDefault();
263         }).mousedown(function(event){
264             stopAll();
265             MAction = true;
266             stx = event.pageX;                
267              event.preventDefault();
268         });
269         eventEle.mouseup(function(event){
270             etx = event.pageX;
271             curX = etx-stx;
272             MAction = false;
273             if(curX>5){
274                 slideAs.attr("href","javascript:void(0)");
275                 toRight();
276             }
277             if(curX<-5){
278                 slideAs.attr("href","javascript:void(0)");
279                 toLeft();
280             }
281              event.preventDefault();
282         });
283     }
284     
285     function touchDrag($element) {
286         var gundongX = 0;
287         var gundongY = 0;
288         var moveEle = $element;
289         var stx = sty = etx = ety = curX = curY = 0;
290         
291         var ImgWidth_arr = [];
292         for (var i = 0; i < imgcount; i++) {
293             ImgWidth_arr.push(i * slideWrapperWidth);
294         }    
295         
296         moveEle.on("touchstart", function(event) { //touchstart
297             stopAll();
298             var event = event.originalEvent;
299             gundongX = 0;
300             gundongY = 0;
301             // 元素當前位置
302             etx = parseInt(getT3d(moveEle, "x"));
303             ety = parseInt(getT3d(moveEle, "y"));
304             // 手指位置
305             stx = event.touches[0].pageX;
306             sty = event.touches[0].pageY;
307         });
308         moveEle.on("touchmove", function(event) {
309             var event = event.originalEvent;
310             // 防止拖動頁面
311             event.preventDefault();
312 
313             // 手指位置 減去 元素當前位置 就是 要移動的距離
314             gundongX = event.touches[0].pageX - stx;
315             gundongY = event.touches[0].pageY - sty;
316 
317             // 目標位置 就是 要移動的距離 加上 元素當前位置
318             curX = gundongX + etx;
319             curY = gundongY + ety;            
320             slideImgWrapper.css({"left":-turnleftwidth+curX});
321             distanceX = curX;
322         });
323         moveEle.on("touchend", function(event) {
324             //alert(gundongX);
325          if(Math.abs(gundongX)>5){
326             event.preventDefault();
327             
328            // 手指接觸屏幕的位置
329             var oriX = etx;
330             var oriY = ety;
331             // 手指離開屏幕的位置
332             etx = curX;
333             ety = curY;
334             var slidePosition = 0;
335             for (var i = 0; i < imgcount - 1; i++) {
336                 if (Math.abs(etx) > ImgWidth_arr[i]) {
337 
338                     if (oriX > etx) {
339                         // 左滑
340                         toLeft();
341                     } else {
342                         // 右滑
343                         toRight();                
344                    }
345                 }
346             }
347          }
348             
349          });
350 
351         function getT3d(elem, ename) {
352             var elem = elem[0];
353             var str1 = elem.style.webkitTransform;
354             if (str1 == "") return "0";
355             str1 = str1.replace("translate3d(", "");
356             str1 = str1.replace(")", "");
357             var carr = str1.split(",");
358 
359             if (ename == "x") return carr[0];
360             else if (ename == "y") return carr[1];
361             else if (ename == "z") return carr[2];
362             else return "";
363         }
364     }
365 }); 
366 }; 
367 })(jQuery); 
View Code

 在線演示web

3.總體思路canvas

a.建立顯示窗口,顯示容器大小位置自定義;vim

b.創立圖片容器,經過改變圖片容器的位置來改變顯示窗口中展現的圖片。瀏覽器

  難點在於如何改變圖片容器位置來顯示須要的圖片和無縫輪播。能夠想象一下之前的膠帶式電影,若是放映速度慢下來就跟圖片輪播相似了。因此能夠把圖片容器當作膠帶,圖片就是其中的一幀圖像,顯示窗口就是電影屏幕。

  若是以一個顯示窗口的寬爲一個單位,咱們把圖片水平排放在圖片容器中,每張圖片剛好佔用一個顯示窗口的寬高,有多少張圖片,圖片容器的寬就爲多少個單位寬。而後使圖片向左移動一個單位的距離,就能夠展現下一張圖片了。爲了使圖片展現效果更美觀,我用了jquery的動畫效果animate()來改變圖片容器的位置。若是設定間隔多少時間圖片容器左移一個單位,達到最後一張圖片時,圖片容器恢復到原始位置,進行下一輪移動。這樣,就能夠實現圖片的水平輪播了。至於無縫輪播,我採起的作法是把前兩張圖片複製一份,放到全部圖片的最後面。首次顯示第二張圖片,當移動到倒數第二張圖片時,在下一次移動時先改變容器的left,讓第一張圖片被顯示出來,由於這個動做很快,看起來好像並無進行任何操做(達到欺騙眼球的效果,呵呵),而後使用animate顯示第二張圖片,在視覺上實現無縫輪播。從第二張圖片右移時也與此相似。這樣作的主要目的是爲了確保左右都有能被展現的圖片,確保不會顯示空白,以實現無縫切換。這裏,會用到的主要知識點有:

  (1).setTimeout和clearTimeout:

  用於延遲執行、循環執行和終止循環。setTimeout延遲執行肯定圖片的顯示時間,循環執行爲了自動展現下一張圖片。當須要中止輪播的時候就能夠用clearTimeout來終止循環了。關於setTimeout和clearTimeout的具體用法,能夠參照代碼,這裏就再也不贅述了。

  (2).jquery選擇器:

  無需多說,全部jquery動做的基礎。

  (3).jquery操做css:

  爲了保證使用的簡單性,只需肯定顯示容器的樣式(需確保overflow:hidden;插件中已設置),其子元素包括圖片容器(這裏只支持div標籤slideWrapper.children('div:eq(0)'))和圖片及其連接的樣式都在插件中肯定,包括:保證圖片水平排列,大小剛好爲顯示窗口的大小;肯定圖片容器的大小剛好容下全部圖片。

  (4).jquery添加元素insertAfter:

  複製前兩張圖片到全部圖片的最後面$((slideImgWrapper.html().split("/div>")[0]+"/div>"+slideImgWrapper.html().split("/div>")[1]+"/div>")).insertAfter(slideAWra.last())。

  (5).jquery動畫效果animate: 

 1 var turnleftwidth = slideWrapperWidth;
 2     function turnleft(){
 3         turnleftwidth = turnleftwidth+slideWrapperWidth;    
 4         if(turnleftwidth>(imgcount-2)*slideWrapperWidth){        
 5             slideImgWrapper.css({'left':0});
 6             turnleftwidth = slideWrapperWidth;
 7         }
 8         slideImgWrapper.stop(true).animate({left:-turnleftwidth},animatetime);                
18     }
19     function turnright(){     
20         turnleftwidth = turnleftwidth-slideWrapperWidth;    
21         if(turnleftwidth==0){        
22             slideImgWrapper.css({'left':-slideWrapperWidth*(imgcount-1)});
23             turnleftwidth = slideWrapperWidth*(imgcount-2);
24         }
25         slideImgWrapper.stop(true).animate({left:-turnleftwidth},animatetime);                
35     }

  其中imgcount爲進行圖片複製後圖片的元素個數,slideWrapperWidth爲顯示窗口的寬。 turnleft()用於無縫左移,turnright()用於無縫右移。

  如今來講說觸屏支持。主要是用了jquery的on方法監聽touch事件。具體怎麼寫,無非就是設置初始觸摸位置,而後監聽滑動的位置,根據水平滑動的具體實時改變圖片容器的left,實現拖拽的效果。滑動結束後根據結束時的位置與初始位置的差判斷左滑仍是右滑,再來改變圖片容器的left,使圖片正好居中顯示。跟PC端的鼠標拖拽相似。說到鼠標拖拽,不得不噴倆句。通常拖拽元素,基本都是mousedown、mousemove、mouseup三部曲。可是碰上圖片就頭疼了,特別是這圖片的父親仍是a標籤。mousedown沒問題,mousemove能一個三五步,mousemove出問題mouseup也就失效了。弄了半天,終於經過 event.preventDefault()實現了對大部分瀏覽器的支持。廢話很少說,讓你們一塊兒糾結下。

 1 <!DOCTYPE html>
 2 <html xmlns="http://www.w3.org/1999/xhtml" lang="UTF-8">
 3 <head>
 4 <meta charset="UTF-8">
 5 <style>
 6     body{
 7         overflow-x:hidden;
 8         margin:0 auto;
 9         padding:0;
10         width: 100%;
11         height: 100%;
12     }
13     .aWrapper{            
14         position: relative;
15         margin:0 auto;
16         width:400px;
17         height:600px;
18         overflow:hidden;
19         //float:left;
20     }
21     .testa{            
22         position: relative;
23         margin:0 auto;
24         width:400px;
25         height:600px;
26         //float:left;
27     }
28     .testimg{            
29         position: absolute;
30         width:400px;
31         height:600px;
32         z-index:0;
33     }
34     .imgmask{            
35         position: relative;
36         width:400px;
37         height:600px;
38         z-index:1;
39         opacity:0.2;
40         background:#333;
41     }
42 </style>
43 </head>
44 <body>
45     <div  class="aWrapper">
46     <a href="http://www.baidu.com"  class="testa">
47         <img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/1 (1).jpg" class="testimg"/>
48         <div class='imgmask'></div>
49     </a>
50     </div>
51 </body>
52 </html>

  上面測試頁面只有在Safari內核的瀏覽器(如Chrome)下才可以拖拽的,並且當圖片遮罩層的position設置爲absolute或者a標籤設置float時都會失效,實在是搞不明白。並且要說一下能夠很容易的阻止事件向上冒泡,有什麼辦法觸發父元素事件是不要觸發子元素的該事件麼?仍是以上面的測試頁面爲例,要拖拽aWrapper的div,就要設置該元素的mousedown、mousemove、mouseup事件。可是這裏有一個問題,在mousedown和mouseup以後會觸發click事件,致使觸發子元素a標籤的click而跳轉頁面。若是僅僅在mouseup時設置a標籤的click返回false,那麼這個連接就永遠失效了。具體處理方法,你們仍是看代碼吧,反正被我搞得複雜得很,說多了都是淚。

  最後說說這個導航欄,就是下面的方方圈圈,用來顯示第幾張和點擊跳轉的。若是直接在頁面上編寫,問題倒還簡單。在JS中就複雜多了。爲了確保插件的獨立性,除了對jquery的依賴外,我不想它有任何其餘依賴。因此通常用圖片來表示狀態的方法就行不通了。我用的是html5的canvas繪製圓形。若是瀏覽器不支持或者擔憂瀏覽器消耗的話,能夠關閉掉,直接用背景色表示,只是只能爲方塊塊了。反正我以爲我本身弄的既不美觀又不優雅,你們就當參照吧。

相關文章
相關標籤/搜索