• iScroll横向滚动区域无法拉动页面的解决方案


    近期项目中使用iScroll遇到一个问题,在设定scroll-box为横向滚动时,如果你手指放在该区域,将无法拉动页面,也就是说该区域取消了默认事件。这个体验是实在是无法接受,这样子照成无法拉动页面,查看滚动区域下面的内容。

    Google了一下子,有个高手给出了解决方案,参考地址:http://stackoverflow.com/questions/7800261/iscroll-with-native-scrolling-on-one-axis

    思路如下:

    我们知道正常调用触摸事件scroll是这样子的  new iScroll("scroll-box",{hScrollbar:false,vScrollbar:false,vScroll:false};

    通过分析iScroll源码发现 再拖动区域触发 touchstart 或者 mousedown事件的时候会首先调用 _start(e);

    源码流程:

    //事件触发
    handleEvent: function (e) {
            var that = this;
            switch(e.type) {
                case START_EV:
                    if (!hasTouch && e.button !== 0) return;
                    that._start(e);
                    break;
                case MOVE_EV: that._move(e); break;
                case END_EV:
                case CANCEL_EV: that._end(e); break;
                case RESIZE_EV: that._resize(); break;
                case 'DOMMouseScroll': case 'mousewheel': that._wheel(e); break;
                case TRNEND_EV: that._transitionEnd(e); break;
            }
        }
    //触发_start(e)
    _start: function (e) {
            var that = this,
                point = hasTouch ? e.touches[0] : e,
                matrix, x, y,
                c1, c2;
    
            if (!that.enabled) return;
    
            if (that.options.onBeforeScrollStart) that.options.onBeforeScrollStart.call(that, e);
    。。。。。
    
    //触发onBeforeScrollStart
    onBeforeScrollStart: function (e) { e.preventDefault(); },

    从代码中我们可知 我们调用new iScroll("scroll-box",{hScrollbar:false,vScrollbar:false,vScroll:false};的时候 首页会调用

    onBeforeScrollStart : function(){
    e.preventDefault();
    }

    它默认是直接取消默认事件的 
    因此需要重写onBeforeScrollStart事件,判断touch的滑动距离,只在横向滑动距离大于竖向滑动距离时(也就是左右滑动时)才取消默认事件,这样就不影响页面滚动了

    代码如下:

    new iScroll("scroll-box",{hScrollbar:false,vScrollbar:false,vScroll:false, 
    onBeforeScrollStart: function ( e ) {
    if ( this.absDistX > (this.absDistY + 5 ) ) {
    e.preventDefault();
    }
    }
    
    }

    到这里的时候感觉就不错了。但是不要高兴的太早。

    上下滑动横向滚动区域,页面确实可以滚动了,但在多体验了几次页面之后,又出现了一个问题。

    先左右滑动该区域,滚动停止后再按住该区域想滚动页面,你会发现它还是不能滚动页面,这时你再点击一次该区域,这时可以了。这相对于你需要触摸2次才能滚动页面, 这样的行为还是让人无法接受。

    经过多翻测试,我把问题锁定到absDistX/Y上。最后发现,在左右滑动之后absDistX/Y的值不会重置,第二次滑动该区域时执行onBeforeScrollStart事件,里面absDistX/Y值是上一次的值,所以程序还是阻止了页面滚动。

    代码如下:

    new iScroll("scroll-box",{hScrollbar:false,vScrollbar:false,vScroll:false, 
                                onBeforeScrollStart: function ( e ) {
                                    if ( this.absDistX > (this.absDistY + 5 ) ) {
                                        e.preventDefault();
                                    }
                                   },
                                //解决第一次无法滑动的问题
                                onTouchEnd: function () {
                                    var self = this;
                                    if (self.touchEndTimeId) {
                                       clearTimeout(self.touchEndTimeId);
                                    }
                                    self.touchEndTimeId = setTimeout(function () {
                                        self.absDistX = 0;
                                        self.absDistY = 0;
                                    }, 600);
                                }
                                });

    在onTouchEnd里面做处理,每次滑动之后都重置absDistX/Y的值。

    这下OK 搞定了! 

  • 相关阅读:
    mysql存储过程的优点
    MySQL复制
    优化数据库的方法
    MySQL表分区
    Http请求
    memcache和redis的区别
    触发器实现原理
    PHP常见数组函数与实例
    git 打包指定提交过的代码
    发送HTTP请求方法
  • 原文地址:https://www.cnblogs.com/qgd87/p/3401898.html
Copyright © 2020-2023  润新知