• zepto.js中的Touch事件


      在移动端经常需要处理滑动事件,比如banner图的左滑右滑,都需要事件响应,这在PC端是没有这类事件的。而在zepto.js中,下载下来的代码也并没有自动加上对这类事件的支持,但是有提供相应的模块,需要你自己加上去(下表中最后一个touch模块):

    moduledefaultdescription
    zepto 核心模块;包含许多方法
    event 通过on()off()处理事件
    ajax XMLHttpRequest 和 JSONP 实用功能
    form 序列化 & 提交web表单
    ie 增加支持桌面的Internet Explorer 10+和Windows Phone 8。
    detect   提供 $.os和 $.browser消息
    fx   The animate()方法
    fx_methods   以动画形式的 showhidetoggle, 和 fade*()方法.
    assets   实验性支持从DOM中移除image元素后清理iOS的内存。
    data   一个全面的 data()方法, 能够在内存中存储任意对象。
    deferred   提供 $.Deferredpromises API. 依赖"callbacks" 模块. 
    当包含这个模块时候, $.ajax() 支持promise接口链式的回调。
    callbacks   为"deferred"模块提供 $.Callbacks
    selector   实验性的支持 jQuery CSS 表达式 实用功能,比如 $('div:first')el.is(':visible')
    touch   在触摸设备上触发tap– 和 swipe– 相关事件。这适用于所有的`touch`(iOS, Android)和`pointer`事件(Windows Phone)。

      这些模块的代码可以直接加在zepto.js的最底部,像拼积木一样,选择模块然后加上去拼合一份适合自己项目的加强版zepto.js。

      关于代码中是如何实现的事件这里不做过多解读,核心肯定是通过touch坐标的差值判断到底是左滑还是上滑。这里主要讲的是touch模块中的一个坑,那就是会和国内的主流手机浏览器的默认事件冲突。具体表现就是,给一个元素绑定左滑动后,在UC浏览器中滑动该元素会出现页面被切换的情况。

      简单的测试发现:UC/QQ都与touch事件发生冲突,安卓自带浏览器和谷歌浏览器不会有此现象。touch这个脚本本来就是外国人写的,当然就无视中国特色了。这里对touch做了一些简单的修改,达到避免这种冲突发生。

      首先引入zepto(已包含touch)之后,代码如下:  

    $('#div').swipeLeft(function(e){
         alert(1);	  	 
    })
    

      在PC上用谷歌开发工具模拟器看,没有任何问题。

      在手机上用UC或者QQ看,悲催了,页面直接被滑跑了。你可以试试,体验一下总比别人告诉你印象深刻。

      很明显,这里需要阻止默认事件,比如这样改一改:  

    $('#div').on('touchstart',function(e){
       e.preventDefault();
    }).swipeLeft(function(e){
       alert(1);	  	 
    })
    

      手机上便可以弹出1。然后事情并没有结束。

      首先这样写太丑陋了,每个swipe之前都要去阻止默认事件,更加难以接受的是,这个时候我上下滑动该元素也会阻止默认事件,也就意味着,当页面需要正常上下滚动的时候,手指在该元素上将滑动不了!

      好吧,那我就去改touch。

      首先,找到touch事件快捷绑定的代码块:  

    ;['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(m){
        $.fn[m] = function(callback){  
          return this.bind(m, callback) 
        }
    })
    

      修改如下:

    ;['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(m){
        $.fn[m] = function(callback){  
          if(!this.data('swipeEvents')){
            this.data('swipeEvents',m);
          }else{
            this.data('swipeEvents',this.data('swipeEvents')+'|'+m);
          }       
          return this.bind(m, callback) 
        }
    })
    

      目的:给所有直接调用swipe的元素,默默的标识上一个数据,该数据就是本元素被绑定的swipe事件的名称,绑定多个swipe时以 | 隔开。

      第二步:找到给body绑定的事件冒泡的touchmove事件代码:

    .bind('touchmove', function(e){
          cancelLongTap()
          touch.x2 = e.touches[0].pageX
          touch.y2 = e.touches[0].pageY
    })
    

      修改为:

    .bind('touchmove', function(e){
          cancelLongTap()
          touch.x2 = e.touches[0].pageX
          touch.y2 = e.touches[0].pageY
          
          if(touch.el&&touch.el.data('swipeEvents')){  
            if(Math.abs(touch.x2-touch.x1)>4&&/Left|Right/.test(touch.el.data('swipeEvents'))){
              e.preventDefault();
            }else if(Math.abs(touch.y2-touch.y1)>4&&/Up|Down/.test(touch.el.data('swipeEvents'))){
              e.preventDefault();
            }
          }      
     })
    

      目的:只要该元素绑定了swipe事件,并且滑动轨迹和swipe事件匹配上,则阻止默认事件。这样,匹配不上的将不被阻止,比如你只是绑定的左右滑动,当touch是上下滑动的时候,不会执行到preventDefault。

      经过UC和QQ测试都没有问题。

      但是,事情还是没有结束。因为,你只要换个方式绑定swipe就挂了,比如这样子:  

    $('#div').on('swipeLeft',function(e){
    

      因为我们只给$.fn[swipe]的时候做了处理,也就是元素直接调用siwpe方法时,才会有效,一旦调用on方法就嗝屁了。当然,一般元素直接调用swipe就可以了,但是如果想用到事件委托,给大量元素批量绑定的时候就必须用到on啊,这怎么办?不好意思,我这里没有给出好办法,因为on这个方法不好改也不能改,改touch已经是心惊胆战了,直接改zepto水平不够。所以暂时还没想到最好的办法,谁知道完美解决办法的请留言。

       

  • 相关阅读:
    eureka_feign学习_1
    九度 题目1183:守形数----------------我用的方法自创
    题目1179:阶乘-------------阶乘不用long long int 就不能AC
    题目1177:查找---------------字符串的函数问题
    题目1170:找最小数-------------------------------找最小值,中间值应该初始化为最大值
    题目1169:比较奇偶数个数-----------------------------这个世界不是奇数就是偶数l
    题目1075:斐波那契数列
    题目1070:今年的第几天?---------关键是闰年的判断
    题目1068:球的半径和体积----------------------------arccos(-1)要用c语言中的acos(-1)代替
    题目1067:n的阶乘--------long long int
  • 原文地址:https://www.cnblogs.com/webLilingyun/p/5542283.html
Copyright © 2020-2023  润新知