• 安卓部分机型touch 事件失效的hack方式


    常规写一段滑动代码,我们可能这么写

    initEvent: function () {
                this.el.addEventListener("touchstart", this.touchStart.bind(this));
                this.el.addEventListener("touchmove", this.touchMove.bind(this));
                this.el.addEventListener("touchend", this.touchEnd.bind(this));
            },
            touchStart: function (e) {
                var touches = e.touches[0];
                this.startStatus = {
                    x: touches.pageX,
                    time: Date.now()
                }
    
                this.validSlide = false;
            },
            touchMove: function (e) {
                var touches = e.touches[0];
    
                e.preventDefault();
    
                this.endStatus = {
                    x: touches.pageX,
                    time: Date.now()
                }
    
                this.delta = {
                    x: this.endStatus.x - this.startStatus.x,
                    time: this.endStatus.time - this.startStatus.time
                }
    
                this.translate(this.delta.x + 'px', 0);
                this.validSlide = true;
            },
            touchEnd: function (e) {
                if (this.validSlide) {
                    var deltaX = Math.abs(this.delta.x),
                        dir = this.delta.x / deltaX,
                        con = (deltaX > window.innerWidth / 3 || this.delta.time < 250 && deltaX > 20)
                            && ((this.delta.x > 0 && this.el.querySelector('.prev')) || (this.delta.x < 0 && this.el.querySelector('.next')));
                    if (con) {
                        this.translate(dir * window.innerWidth + 'px', this.speed);
    
                        setTimeout(function () {
                            window.s.trigger('slide', [dir]);
                        }, this.speed);
                    } else {
                        this.translate('0px', this.speed);
                    }
                }
            },
    

     直接复制粘贴,请忽视相关业务代码。一般在touchmove中加e.preventDefault()来防止安卓手机只触发一次move和不触发end事件的问题和一些浏览器默认行为。

    但是这样还是会在安卓部分机型,例如三星手机中出现不触发touch事件的问题(start,move,end均不触发),经测试如果给document也绑定一个touchmove事件来阻止浏览器默认动作

        document.addEventListener("touchmove", function (e) { e.preventDefault();}); 
    

      此时发现相关的dom能滚动了,但是浏览器一些默认行为例如滚动滑屏也被阻止了。

    于是在绑定函数里做文章

    document.addEventListener("touchmove", function (e) {
            if(bubblingToEle(e.target, 'id', 'detail_view')){
                e.preventDefault();
            }
        });
    

    其中bubblingToEle判断是否冒泡到id位detail_view的节点上,详见

    var bubblingToEle =  function (target, type, value) {
                while(target){
    
                    switch (type){
                        case 'id':
                            if(target.id === value){
                                return target;
                            }
                            break;
    
                        case 'nodeName':
                            if(target.nodeName === value){
                                return target;
                            }
                            break;
    
                        case 'className':
                            if(target.classList.contains(value)){
                                return target;
                            }
                            break;
    
                        default :
                            break;
                    }
    
                    target = target.parentNode;
    
                    if(target.nodeName === 'HTML'){
                        break;
                    }
                }
                return null;
            }
    

      此时算是hack了这个三星手机上出现的问题,绑定在具体的滑动节点的move事件的preventDufault是不生效的,得在document上也绑定一个,具体其中的黑科技猜测应该是以前的一个浏览器的一个bug吧,部分手机厂商还在用以前用bug的分支,这也可能跟我滑动的写法有关,之前都是js动态写style来控制滑动,这次是采用了三个class,把样式写到了css里,所以可能才出现的这个bug,但是由于整体布局定下来了,所以就不改这里了。因为这个写法在opera浏览器里也存在问题,opera是判断滑动的父层是否有transition这个属性,如果有就不进行内置的history的back或者forward,所以这次写在css里的transform也导致左滑的时候在opera表现为回退。详见轻量级移动端滑动xwipe.js,这个写法在三星手机和opera是没问题的,所以猜测这次出现bug的原因可能是由于把transform相关的样式写在了css里原因,具体没有验证。

    或者谁有更好的解决办法请不吝赐教。

     -------------------------------------

    更新一下欧朋浏览器左滑触发回退的问题,当父层有transtion属性的时候,欧朋浏览器不会触发回退。

    --------------------------------------------

    顺便补充一个vivo自带浏览器在scroll的时候会触发window的resize事件,这个就有点坑爹了,解决方法定义一个lastWinWidth,resize的时候判断window.innerWidth和lastWinWidth是否相等,不等再进行resize操作。

      

  • 相关阅读:
    Unity 网络通信以及buffer优化
    Unity 滑动列表ScrollRect制作
    Unity中一些辅助工具类
    一个欠揍的广告语
    翻译:使用 Asp.net mvc 15 分钟创建 Movie 数据库应用程序
    [转]如何查找.NET程序内存不断上涨的原因(CLRProfiler)
    [转载]SQL语句的解析过程
    [转]C#汉字转换拼音技术详解(高性能)
    adb devices 找不到设备的解决方法
    JS中对象object的复制
  • 原文地址:https://www.cnblogs.com/childsplay/p/5477328.html
Copyright © 2020-2023  润新知