博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
支持触屏的jQuery轮播图插件
阅读量:4982 次
发布时间:2019-06-12

本文共 12974 字,大约阅读时间需要 43 分钟。

移动轮播图我看到两类,

一款是无线天猫的m.tmall.com和携程,实现了无缝轮播。

一款是蘑菇街的,没有实现无缝轮播。

我自己重写一个,类似天猫。

1.页面代码

1  2  3  4     
5 基于jQuery的移动轮播图(支持触屏) 6
7 8 47 48 49 50 51 52 53 54
55 56
57 58
59
60
61
62 63
64 65
66
67
68
69
70
71
72 73
74 85 86
View Code

2.js插件代码

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             $("
").insertAfter(slideImgWrapper); 38 navimgs = slideWrapper.children('div:last'); 39 navimgs.append("
"); 40 circlewrapper = navimgs.children('div:first'); 41 for(var i=0;i
"); 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
(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
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) { //touchstart297 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

3.整体思路

a.创建显示窗口,显示容器大小位置自定义;

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  2  3  4 
5 43 44 45
46
47 48
49
50
51 52

  上面测试页面只有在Safari内核的浏览器(如Chrome)下才能够拖拽的,而且当图片遮罩层的position设置为absolute或者a标签设置float时都会失效,实在是搞不明白。而且要说一下可以很容易的阻止事件向上冒泡,有什么办法触发父元素事件是不要触发子元素的该事件么?还是以上面的测试页面为例,要拖拽aWrapper的div,就要设置该元素的mousedown、mousemove、mouseup事件。但是这里有一个问题,在mousedown和mouseup之后会触发click事件,导致触发子元素a标签的click而跳转页面。如果仅仅在mouseup时设置a标签的click返回false,那么这个链接就永远失效了。具体处理方法,大家还是看代码吧,反正被我搞得复杂得很,说多了都是泪。

  最后说说这个导航栏,就是下面的方方圈圈,用来显示第几张和点击跳转的。如果直接在页面上编写,问题倒还简单。在JS中就复杂多了。为了确保插件的独立性,除了对jquery的依赖外,我不想它有任何其他依赖。所以一般用图片来表示状态的方法就行不通了。我用的是html5的canvas绘制圆形。如果浏览器不支持或者担心浏览器消耗的话,可以关闭掉,直接用背景色表示,只是只能为方块块了。反正我觉得我自己弄的既不美观又不优雅,大家就当参照吧。

  

 

转载于:https://www.cnblogs.com/crookie/p/3776670.html

你可能感兴趣的文章
大战设计模式【23】—— 原型模式
查看>>
Chapter 5 Blood Type——32
查看>>
deepClone
查看>>
初探nginx——安装
查看>>
03-imp导入指令.sql
查看>>
python 中numpy中函数hstack用法和作用
查看>>
ARM debian的图形界面安装
查看>>
神经网络架构PYTORCH-前馈神经网络
查看>>
题目557-奇数的个数-nyoj20140812
查看>>
CodeForces 404C Ivan and Powers of Two
查看>>
在Centos上面用yum不能安装redis的朋友看过来
查看>>
java环境搭建个人注意
查看>>
C#基础类与接口的选择
查看>>
floating-camera
查看>>
mips gnu工具使用
查看>>
[javascript]event属性
查看>>
FTP操作(FTPClient)
查看>>
php防sql注入、xss
查看>>
数电碎片
查看>>
JavaBean的实例--邮件发送JavaBean:基于Javax.mail
查看>>