首页 > 代码库 > 解决Android下元素滑动问题

解决Android下元素滑动问题

 

移动端左右、上下滑动:
当页面中既需要页面滑动操作,又需要上下或左右滑动页面上的某个元素时,直接使用zepto中提供的swipe事件是不能直接达到目的的,原因如下:
(1)在Android低端机上touchEnd会不被触发。
(2)zepto中的swipe 事件通过 事件冒泡机制实现事件监听
在document上统一监听touchstart、 touchmove、 touchend, 然后判断是上下滑动还是左右滑动。 再判断document的touch事件是由哪个元素上的touch事件冒泡上来的, 再触发该元素上的滑动事件。
直接在某个元素上绑定swipe事件,会冒泡至body上,如果是上下滑动会触发页面滚动,导致在滑动元素的时候页面也在滚动。
滑动事件触发过程:
(1)IOS 上 当触发 "swipe"时, 依次产生如下事件: touchstart - > touchmove * 多次 - > touchend - > scroll
(2)Android4.x上touchend不触发-- > touchmove时, 阻止默认事件, touchend才会被触发
touchstart - > touchmove - > touchcancel - > scroll * 多次
并且在Android低版本上还会出现单击一下,会有位移差的现象。

 

所以,通过下面脚本重写swipe事件,解决上面的问题。

/**
 * 滑动事件   Android 4.0 will not fire touchend event
 */
define(function(require,exports,module){

     function SwipeEvent(selector){
        this.selector = selector;
        this.swipeLeftCallback = function(){};
        this.swipeRightCallback = function(){};
        this.swipeUpCallback = function(){};
        this.swipeDownCallback = function(){};
        this._initSwipe(selector);
    }
    SwipeEvent.prototype.bind = function(evtName,callback){
        switch(evtName){
            case "swipeLeft":
            this.swipeLeftCallback = callback;
            break;
            case "swipeRight":
            this.swipeRightCallback = callback;
            break;
            case "swipeUp":
            this.swipeUpCallback = callback;
            break;
            case "swipeDown":
            this.swipeDownCallback = callback;
            break;
        }
    };
    SwipeEvent.prototype._initSwipe = function(selector){
        var self = this;
        var startX, startY;
        var endX, endY;
        var distanceX, distanceY;
            $(selector).on(‘touchstart‘, function(event) {
                startX = event.targetTouches[0].clientX;  //位于当前DOM元素上手指的列表。
                startY = event.targetTouches[0].clientY;
            }).on("touchmove",function(event){
                endX = event.changedTouches[0].clientX;
                endY = event.changedTouches[0].clientY;   //涉及当前事件手指的列表。
                distanceX = Math.abs(startX - endX);
                distanceY = Math.abs(startY - endY);
                if(distanceX > 1 || distanceY > 1){  //判断是左右滑动或上下滑动,阻止默认事件  使android4 touchend生效
                    event.preventDefault();
                }
                event.stopPropagation();
            }).on(‘touchend‘, function(event) {
                endX = event.changedTouches[0].clientX;
                endY = event.changedTouches[0].clientY;
                distanceX = Math.abs(startX - endX);
                distanceY = Math.abs(startY - endY);
                if(distanceX > 10 || distanceY > 10){  //安卓4.X里,单击一次也会产生位移差
                    if (distanceX >= distanceY) {  //左右滑动
                        if(startX - endX > 0){
                            self.swipeLeftCallback(event);
                        }else if(startX - endX < 0){
                            self.swipeRightCallback(event);
                        }
                    }else{
                        if(startY - endY > 0){
                            self.swipeUpCallback(event);
                        }else if(startY - endY < 0){
                            self.swipeDownCallback(event);
                        }
                    }
                }
            });
    };
    module.exports =  SwipeEvent;
});

 参考:http://www.cnblogs.com/ytu2010dt/p/5767491.html

http://www.myexception.cn/web/1874295.html

解决Android下元素滑动问题