用智能手机浏览网页,常常发现许多惊艳的滑动效果。垂直方向的滑动是智能手机的固有属性,这其实不算滑动,是滚屏而已。但有些横向滑动的效果,比如打开网易手机版:http://3g.163.com/touch/,还是比较炫的,好像也是一个网站手机版的标准配备。
这种效果怎么弄出来呢?网易这个代码是加了密的,看不懂,注释显示,好像是用了老外的一个什么包,我英文差,没功夫去研究。在网上疯狂搜索,发现有篇大牛的文章,拿来试了一下,可以用,很不错。
不过大牛的效果是比较基本的,事先放置了3个块,每块显示一屏,但不能循环,向两边各滑动一两次就一片空白了,没有实现环形的滑动;另外它进入空白地带后,还是可以继续滑动,相当于将页面可见内容越滑越远。
我们做这个滑动效果,是为了更好地呈现数据,所以我又花了一些工夫进行修改,以期能应用到实际工作中。
1、滑动效果是为了更好地呈现数据,滑动效果一般有3块就行了,每次显示一块,余下两块分别移到当前块的左右两侧;而数据则可能有好多。所以数据和滑动块要分离,需要时才加载到滑动块来显示。如果有多少数据,就设置多少个滑动块,当然最简单,但页面代码也多了不少。
2、滑动块需要循环使用
3、支持触摸,否则在手机浏览器看不到效果
4、只有在滑动块范围内拉动和触摸才有效
没代码我说个J8:
页面
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta content="width=device-width,initial-scale=1.0,user-scalable=no" name="viewport"> <title>循环滑动</title> <style> *{margin:0;padding:0} html,body{overflow:hidden;} #slideView { position:absolute; overflow:hidden; border:solid 1px black; } .slideContainer { position:absolute; } .block{ position:absolute; } .block div{ border:solid 2px black; margin:auto; font-size:1.5em; color:black; 60px; height:60px; text-align:center; line-height:50px; background-color:#fff; } .debug{ color:Black; } #divColor td{border:solid 1px black;} </style> <script src="/js/jquery-1.7.1.min.js"></script> <script src="/js/slide.js"></script> </head> <body> <div class="debug" style="padding-left:30px;">滑呀滑呀</div> <div id="divPlaceholder"> <div id="slideView"> <div class="slideContainer"> <div class="block"> <div>1</div> </div> <div class="block"> <div>2</div> </div> <div class="block"> <div>3</div> </div> </div> </div> </div> <div> <div id="divColor"></div> <div>赤橙黄绿青蓝腚 谁持厕纸当空舞?</div> </div> </body> </html>
slide.js
//----------------------------------------------------------------------------------- // “虚”函数,可以由调用方改写 //----------------------------------------------------------------------------------- //初始化 var slide_func_Init = function(){ //高度自适应..宽度为显示器宽,设置容器的大小和位置 window.winWidth = _slide_width; var width = _slide_width; var height = _slide_height - 150; //占位,由于滑动块父容器是position:absolute,用这个DIV将它包容起来,利于上下的排版 var placeholder = $("#divPlaceholder"); placeholder.css("width", width); placeholder.css("height", height); //观看滑动块的视图 var view = $("#slideView"); view.css("width", width); view.css("height", height); //滑动块父容器 slide_container = $(".slideContainer"); //滑动块 var slideList = $(".block");//待滑动的块 slideList.css("width", width); slideList.css("height", height); var slideLen = slideList.length; var block = new Array(); for( var i = 0; i < slideLen;i++) { block[i] = slideList.eq(i); } slide_blockShow = block; //待加载数据 slide_blockData = new Array("#999","#f00","#0f0","#00f","#ff0","#0ff","#000"); var tbcolor ="<table><tr>"; for(var i = 0;i < slide_blockData.length;i++){ tbcolor += "<td style='background-color:" + slide_blockData[i] + "'> </td>"; } tbcolor += "</tr></table>"; $("#divColor").html(tbcolor); document.body.parentNode.style.overflow="hidden"; } //滑动块数据加载 var slide_func_ShowBlock = function(p,ari){ var i = ari[0]; var il = ari[1]; var ir = ari[2]; var arj = _slide_func_GetPointer(p,slide_blockData.length); var j = arj[0]; var jl = arj[1]; var jr = arj[2]; slide_blockShow[i].css("background-color", slide_blockData[j]); slide_blockShow[il].css("background-color", slide_blockData[jl]); slide_blockShow[ir].css("background-color", slide_blockData[jr]); } var slide_func_debug = function(text){ $(".debug").text(text); } //----------------------------------------------------------------------------------- // 全局变量 //----------------------------------------------------------------------------------- var slide_container; //滑动块容器 var slide_blockShow; //滑动块,应该有3个 var slide_blockData; //用于在滑动块上显示的数据,数量不限,但多于3个那是肯定的 var _slide_width = window.screen.width; var _slide_height = (window.screen.height > 500) ? 500 : window.screen.height; //----------------------------------------------------------------------------------- // 私有函数 //----------------------------------------------------------------------------------- $(document).ready(function(){ _slide_func_disRightMouse(); var startX; var basePoint = 0; var stargDis; var distance; var maxDistance = 50; var doc = $(document); var animateSpeed = 800; var recoverSpeed = 100; var width = _slide_width; var yT,yB; var p; slide_func_Init(); var container = slide_container; if(container == null){ alert("还没有设置滑动块容器!"); } var blockShow = slide_blockShow; if(blockShow == null || blockShow.length < 3){ alert("还没有设置滑动块或滑动块数量少于3个!"); } yT = blockShow[0].offset().top; yB = yT + blockShow[0].height(); //鼠标大人,乃过气之物?妇人之屁鬼如鼠,壮士之屁猛若牛 doc.mousedown(function(event){ startX = event.clientX; doc.bind("mousemove", moveHandler); startX = event.clientX; }); doc.mouseup(function(){ if(distance < maxDistance){ recoverPosition(distance); } doc.unbind("mousemove"); }); function moveHandler(event){ var y = event.clientY; if( y < yT || y > yB) return; distance = event.clientX - startX; movePanel(distance); if(event.clientX - startX > maxDistance){ doc.unbind("mousemove"); slideRight(); return; } if(event.clientX - startX < -maxDistance){ doc.unbind("mousemove"); slideLeft(); return; } } //touch...别摸我 try{ document.addEventListener('touchstart',function(ev){ startX = ev.touches[0].pageX; touchBind(ev); },false); document.addEventListener('touchend',function(ev){ if(distance < maxDistance){ recoverPosition(distance); } touchUnBind(); },false); }catch(ex){} function touchBind(ev){ document.addEventListener('touchmove',touchHandler,false); } function touchUnBind(){ document.removeEventListener('touchmove',touchHandler,false); } function touchHandler(ev){ var y = ev.touches[0].pageY; if( y < yT || y > yB) return; distance = ev.touches[0].pageX - startX; movePanel(distance); if(ev.touches[0].pageX - startX > maxDistance){ slideRight(); touchUnBind(); return; } if(ev.touches[0].pageX - startX < -maxDistance){ slideLeft(); touchUnBind(); return; } } function recoverPosition(dis){ container.animate({ left : basePoint }, recoverSpeed ); dis = 0; } function movePanel(distance){ container.css("left", basePoint + distance); } function slideRight(){ container.animate({ left : basePoint += width }, animateSpeed); p--; ShowBlock(p); } function slideLeft(){ container.animate({ left : basePoint -= width }, animateSpeed); p++; ShowBlock(p); } function ShowBlock(p){ var ari = _slide_func_GetPointer(p,blockShow.length); var i = ari[0]; var il = ari[1]; var ir = ari[2]; var sleft = blockShow[i].css("left"); var left = sleft.substring(0,sleft.indexOf("px")) * 1; blockShow[il].css("left", (left - width) + "px"); blockShow[ir].css("left", (left + width) + "px"); slide_func_ShowBlock(p,ari); } p = 0; ShowBlock(p); }) function _slide_func_GetPointer(p,len){ var min = 0; var max = len - 1; var i = p; if(i < 0){ i = len - (i * -1) % len; } i = i % len; var il = (i > min) ? i - 1 : max; var ir = (i < max) ? i + 1 : min; return [i,il,ir]; } function _slide_func_disRightMouse(){ $(document).bind("contextmenu",function(e){ return false; }); }
代码说明:
1、手机浏览器有touch事件,但PC浏览器没有。所以要用try catch
2、不知道为什么,用手机浏览,页面宽度会比手机屏幕要宽,搞得向左拉动的时候,首先是滚屏效果,然后再到滑动,要拉动好长一段距离。所以要用一个DIV将滑动块及其父容器套住,严格定死宽度与屏幕一致,还要设置overflow属性。
#slideView { position:absolute; overflow:hidden; border:solid 1px black; }
我将这个DIV称为视窗,透过它我们可以看到滑动块,而页面手机屏幕则再也没有被撑开的问题了。
3、滑动块及其父容器、视窗,都是绝对定位。为了上下文排版,需要用一个没有绝对定位的DIV(<div id="divPlaceholder">)将他们套住,宽高跟他们保持一致。
4、
<meta content="width=device-width,initial-scale=1.0,user-scalable=no" name="viewport">这一句很重要,规定页面宽度与手机屏幕一致。我查了一下,是HTML5的东西。靠,HTML5,我不懂耶。
参考文章:
http://www.cnblogs.com/xesam/archive/2012/05/18/2484426.html