轻量级移动端滑动xwipe.js

工作需要写一个移动端的滑动效果,参考了swipe,和iscroll之后自己写了一个xwipe。在写的过程中学习了很多,分享一下心得。

首先html和css部分和swipe一样。

html部分

xwipe结构
<div id=‘xwipe‘ class=‘xwipe‘>
    <div class=‘xwipe-wrap‘>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        ..
    </div>
</div>

tab结构
<ul id="tab" class="tab clearfix">
    <li>0</li>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    ...
</ul>

  css部分

.xwipe {
    overflow: hidden;
    visibility: hidden;
}
.xwipe-wrap {
    overflow: hidden;
}
.xwipe-wrap > div {
    float:left;
    position: relative;
}

  主要说下js部分的心得和坑

1.第一个心得是在写绑定touch事件的时候,开始这么绑定

el.addEventListener("touchmove", function(){}, false);

  这样就有一个问题,必须在外面定义一个_this = this把Xwipe对象的this给存到一个变量里,不然监听事件函数里的this就指向了el本身,就不能继续调用Xwipe的方法。
之前遇到定时器或者绑定事件也都是这么解决的。但是这次由于各个方法之间相互调用把this定义变量当参数的方式会让整个逻辑非常乱。查看了swipe和iscroll才发现构造函数的

handleEvent方法,这个可以方法可以在事件触发的时候被调用,这样就统一了this指向的问题。具体实现方法是
el.addEventListener(type, this, false);

handleEvent : function(e){
        switch (e.type){
            case ‘touchstart‘:
                this.touchStart(e);
                break;
            ...
    }

  这样就可以在el被touchstart的时候触发Xwipe的touchStart方法了。但是这里同时就有一个问题了,如果这里有两个dom对象绑定事件的type都是一样的话,这里该怎么处理?

我觉得这种情况出现的不多,毕竟是一个类,dom对象也是基于一个div整体,如果真出现两个type一样的话,可以把这两个事件委托给这个div整体,或者其他有什么好的处理方法?

2.在写touchMove的时候为了阻止浏览器默认的滚动事件,在方法开始就写了

e.preventDefault();来阻止浏览器默认动作,这个在单个测试的时候没有测出什么问题,但是放到具体页面的时候,特别是实例出来多个对象的时候,明显感觉是不科学的,因为这部分无法上下滑动了。
所以在touchMove开始触发的时候加上了先判断是否是上下滑动,如果是,则不preventDefault且不进行xwipe动画。

3.setTimeout(function(){},0)的作用。

先说下Xwipe的滑动逻辑,如果滑到最后一个,再向右滑的话,第一个出现。这里没有添加是否形成这个循环的配置。所以目前Xwipe只能循环滑动。

从当前index跳到goTo指定的to页面的时候,是判断index到to的顺时针和逆时针的距离,优先想近的方向滑,具体代码实现

getDirection : function (to) {
        return (to - this.options.curIndex)*(Math.abs(to - this.options.curIndex) > this.sLength/2 ? -1 : 1) > 0 ? 1 : -1; //1向右滑动,-1向左滑动
},

  比如现状当前页是1,goto页是7,点击tab7的时候是向左滑动到7。说完背景,说到这里遇到的问题。

还是这个例子,当点击的时候判断出7应该出现在左边的时候,先给7的

translate x设置为-width,然后到正确位置之后,在让7的x过渡到0,1的x过渡到width,这样才能形成一个滑动的效果。具体代码简单例子是这样
slide[7].style.webkitTransform = ‘translate3d(‘ + -width+ ‘px, 0, 0)‘;
slide[7].translate(0);
slide[1].translate(width);

 实际运行的时候浏览器好像不按逻辑来的,仿佛直接忽略了第一步而是直接让7从原来的位置滑动到1,如果7原来的位置是width的话,什么鬼这是?

接着各种查,然后发现很多人都遇到过这个问题,比如creat一个input标签之后直接绑定事件不生效,在好好读一下swipe发现一个不太明白的地方

var offloadFn = function(fn) { setTimeout(fn || noop, 0) };

  这个正常理解就是立即执行啊,遂谷粉搜搜一下,发现这个还真有大作用,具体可以查看这个http://stackoverflow.com/questions/779379/why-is-settimeoutfn-0-sometimes-useful

有了这个大杀器之后,这里就好办了,可以这么改一下上面的代码

slide[7].style.webkitTransform = ‘translate3d(‘ + -width+ ‘px, 0, 0)‘;
setTimeout(function(){
    slide[7].translate(0);
    slide[1].translate(width);
},0)

 这样就可以把两个translate滑动方法移动队列最后去执行,这样就能保证7的位置已经移动到了-width位置。

这个Xwipe还是有很多不足之处的,有很多地方写的都不很满意,

比如处理当slide长度为1或者2的时候做的特殊处理,在逻辑的-1和+1位置都加了一个判断slide.length !=1,一共加了6个。处理长度为2的时候是把这两个slide再append后面去变成4个的情况同时把realLength存储起来,这样就可以循环滑动了。

再比如循环滚动这个配置,本来是想加的,后来发现又要改逻辑部分再加上自己主观认为不循环是反人类的体验,所以就默认了循环滑动了。

写完这个感觉自己学了很多,之前太依赖jq了,现在发现写完之后,h5提供了很多api都非常好用,主要操作dom的jq方法,对应的新增api也不错,而且是做移动端,根本就不需要兼容ie。在测试页面里实例化了10个左右,也没有之前的滑动卡顿的情况。

Xwipe整体借鉴了swipe的思路,新增了一个tab导航。提供了4个简单常用方法

    prev() 滑动到上一个slide
    next() 滑动到下一个slide
    goTo(index) 滑动到指定index索引
    option.curIndex 获取当前索引

最后附上demo地址,下载地址。

时间: 2024-10-06 20:41:48

轻量级移动端滑动xwipe.js的相关文章

开源轻量级移动端友好的JS地图库——leaflet学习教程

Leaflet 是一个为建设交互性好适用于移动设备地图,而开发的现代的.开源的 JavaScript 库.代码仅有 33 KB,但它具有开发在线地图的大部分功能.Leaflet设计坚持简便.高性能和可用性好的哲学思想,在所有主要桌面和移动平台能高效运作,在现代浏览器上会利用HTML5和CSS3的优势,同时也支持旧的浏览器访问.支持插件扩展,有一个友好.易于使用的API文档和一个简单的.可读的源代码.Leaflet强大的开源库插件涉及到地图应用的各个方面包括地图服务,数据提供,数据格式,地理编码,

关于移动端滑动手势

背景: 基于要尝试的移动端项目需要有一个通过上拉下滑手势达成加载不同数据的功能,其涉及到滑动手势和ajax数据加载方面的知识点.故对整个实现过程做一个记录整理.个人JS功底有限,看了诸多例子和对于移动端手势知识点梳理的技术博客才对做到了对功能的实现.并且也在这个过程中,才初步了解到了移动端框架Zepto.js._(:з」∠)_ 当然,最后还是选择了尽量用原生来实现这一个功能,只因为这样才能够对整个功能实现原理理解上更充分些,想尽量少依赖于插件.不过到了数据加载上,因为时间成本等原因最后还是用上了

初试 vue2.0——9.项目开发_better-scroll 实现移动端滑动2

写在前面的话: 上一篇文章实现了滑动效果,这部分来试试左右联动效果的实现方法吧 九.better-scroll + vue2.0 实现移动端滑动2--左右联动 效果:滑动右侧时,左侧也能有相应的变化:点击左侧时,右侧也能自动定位到相应的位置. 如下图所示界面,左侧为分栏,右侧为分栏详情. 滑动右边使左边联动的大概的思路: 1)要知道右侧的列表中,每一个分栏所占的高度,存进一个数组中. 2)实现左边联动,则必须要监控 "scroll"事件,获取其高度 3)将scroll 的高度与右侧分栏

移动端滑动方向判断

移动端滑动方向判断,主要是判断利用x,y轴方向的增量,哪个轴增的快,就是哪个方向. 在touchstart中获取初始点,startX, startY; 在touchmove中获取移动点,moveX, moveY 计算两者的差 deltaX = moveX - startX;  deltaY = moveY - startY; 之后累加deltaX和deltaY: distX += Math.abs(deltaX) distY += Math.abs(deltaY) if (distX > dis

移动端触屏滑动,JS事件

先了解下 移动端的触屏滑动 毕竟这玩意其实和PC端还是有一定的区别的 hh 整理了下网上的资料放一放 移动端触屏滑动的效果其实就是图片轮播,在PC的页面上很好实现,绑定click和mouseover等事件来完成.但是在移动设备上,要实现这种轮播的效果,就需要用到核心的touch事件.处理touch事件能跟踪到屏幕滑动的每根手指. 以下是四种touch事件 touchstart:手指放到屏幕上时触发 touchmove:手指在屏幕上滑动式触发 touchend:手指离开屏幕时触发 touchcan

js移动端滑动事件

1 <div id="box" style="width:100%;height:100%;border:1px solid red;"></div> 2 3 <script> 4 //定义变量,用于记录坐标和角度 5 var startx,starty,movex,movey,endx,endy,nx,ny,angle; 6 //开始触摸函数,event为触摸对象 7 function touchs(event){ 8 even

轻量级移动端日期选择器

在移动端进行日期选择想必困扰过不少小伙伴,在PC端我们比较丰富的选择,如jQueryUI的datepicker,但这些插件都比较臃肿,而 且还要依赖一个同样臃肿的库.或许PC上可以忍受比较大的文件,网速相对快嘛.然而在移动端也面临同样的问题,想用一个日期选择器还得依赖一个庞大的UI 库,如mobiscroll.但移动端的网速慢啊,而且要耗流量,用这么一个大家伙就显得无法忍受. 于是,我决定造轮子了.造一个轻量级的.适合在移动端使用的日期选择器.而且只依赖Zepto.(Zepto本身体积小,而且在

移动端滑动事件

   安卓webview下使用zepto的swipe时遇到的问题    (使用zepto的swipe时必须引用touch.js,不然很多移动端浏览器swipe会失灵.) 我想要用swipeLeft/swipeRight监听向左向右滑动事件,如果只是单纯为元素增加swipeLeft/swipeRight事件的话在webview下是不生效的,如果这个页面不需要上下滑动的话,完全可以用 $('body').bind("touchmove", function(e) { e.preventDe

移动端滑动插件 swiper

swiper.js能适用于用PC网页,也能使用移动端页面,之前用TouchSwipe,感觉没有swiper.js强大,TouchSwipe有一个bug,在滑动区域有连接的时候(大面积的a),默认点击会无效,只能滑动,即时用jq去模拟点击也是失效的,也许是自己没有发现正确使用方法,求问度娘,发现swiper神器... 下面放上代码, //滑动效果 var swiper = new Swiper('.swiper-container', { pagination: '.swiper-paginati