1. 程式人生 > >apicloud學習之路(3)-解決左右滑動和下拉衝突問題

apicloud學習之路(3)-解決左右滑動和下拉衝突問題

在使用apicloud開發app的時候會遇到這樣的問題,左右滑動輪播圖會和下拉重新整理衝突,還有左右滑動輪播圖也會和frame本身的左右滑動切換衝突,經過自己研究記錄下一些解決方法

1.監聽觸控事件禁止和恢復下拉重新整理

2.監聽觸控事件禁止frame的左右滑動切換

3.在輪播圖頻繁滑動問題中會出現問題,使用了函式防抖

4.還有輪播圖上滑的時候頁面滾動有點問題,圖片輪播也在切換,這個問題還未處理(??)

/**
 *  移動端輪播圖
 *  這裡上滑還有點問題,左右輪播帶點上滑
 * @type {{touch: (boolean|*), slider: HTMLElement | null, clientWidth: number, events: {index: number, scrollWidth: number, icons: HTMLElement | null, icon: NodeListOf<HTMLElementTagNameMap[string]>, handleEvent: slider.events.handleEvent, start: slider.events.start, move: slider.events.move, end: slider.events.end}, initStyle: slider.initStyle, init: slider.init}}
 */
var slider = {
    //判斷裝置是否支援touch事件
    touch: ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch,
    slider: document.getElementById('slider'),
    clientWidth: document.body.clientWidth,

    //事件
    events:{
        index:0,     //顯示元素的索引
        // scorllWidth: this.clientWidth,   // 一次滾動的距離, 這裡的this到底指向誰,獲取不到slider物件的資料???如何獲取
        // slider:this.slider,     //this為slider物件
        scrollWidth: document.body.clientWidth,
        icons:document.getElementById('icons'),
        icon:this.icons.getElementsByTagName('span'),
        sliderTimer: null,   // 是否可以輪播滾動,函式防抖控制

        handleEvent:function(event){
            var self = this;     //this指events物件
            if(event.type == 'touchstart'){
                console.log('touchstart')
                self.start(event);
            }else if(event.type == 'touchmove'){
                console.log('touchmove')
                self.move(event);
            }else if(event.type == 'touchend'){
                console.log('touchend')
                self.end(event);
            }
        },
        //滑動開始
        start:function(event){
            // 阻止frame的預設滑動
            api.setFrameGroupAttr({
                name: 'group',
                scrollEnabled: false
            });
            var touch = event.targetTouches[0];     //touches陣列物件獲得螢幕上所有的touch,取第一個touch
            startPos = {x:touch.pageX,y:touch.pageY,time:+new Date};    //取第一個touch的座標值
            console.log(JSON.stringify(startPos))
            isScrolling = 0;   //這個引數判斷是垂直滾動還是水平滾動
            document.getElementById('sliderWrapper').addEventListener('touchmove',this,false);
            document.getElementById('sliderWrapper').addEventListener('touchend',this,false);
        },
        //移動
        move:function(event){
            //當螢幕有多個touch或者頁面被縮放過,就不執行move操作
            if(event.targetTouches.length > 1 || event.scale && event.scale !== 1) return;
            var touch = event.targetTouches[0];
            endPos = {x:touch.pageX - startPos.x,y:touch.pageY - startPos.y};
            console.log(JSON.stringify(endPos))
            isScrolling = Math.abs(endPos.x) < Math.abs(endPos.y) ? 1:0;    //isScrolling為1時,表示縱向滑動,0為橫向滑動
            if (isScrolling == 0) {
              //  水平滑動禁止frame上下抖動
              api.setFrameAttr({
                  name: 'findMusicFrm0',
                  bounces: false
              })
            }
        },
        //滑動釋放
        end:function(event){
            var self = this;
            var duration = +new Date - startPos.time;    //滑動的持續時間
            console.log(isScrolling);
            if(isScrolling === 0){    //當為水平滾動時, 這裡新增一個函式節流
                clearTimeout(self.sliderTimer);
                self.sliderTimer = setTimeout(function () {
                    // console.log(this);  // 定時器裡面的this指向window
                    self.icon[self.index].className = '';
                    if(Number(duration) > 10){
                        //判斷是左移還是右移,當偏移量大於10時執行
                        if(endPos.x > 20){   // 寫小了上滑會翻頁
                            console.log("右滑");
                            if(self.index !== 0) self.index -= 1;
                        }else if(endPos.x < -20){
                            console.log("左滑");
                            if(self.index !== self.icon.length-1) self.index += 1;
                        }
                    }
                    self.icon[self.index].className = 'curr';
                    document.getElementById('slider').className = 'cnt f-anim';
                    document.getElementById('slider').style.left = -self.index * self.scrollWidth + 'px';
                    // 恢復frame的預設滑動
                    api.setFrameGroupAttr({
                        name: 'group',
                        scrollEnabled: true
                    })
                    //  恢復水平滑動禁止frame上下抖動
                    api.setFrameAttr({
                        name: 'findMusicFrm0',
                        bounces: true
                    })
                }, 500)
            }
            //解綁事件
            document.getElementById('sliderWrapper').removeEventListener('touchmove',this,false);
            document.getElementById('sliderWrapper').removeEventListener('touchend',this,false);
        }
    },

    // 初始化樣式
    initStyle:  function() {
        var lis = document.querySelectorAll('#slider li');
        var len = lis.length;
        document.querySelector('.m-slider').style.width = this.clientWidth + 'px';
        document.querySelector('#slider').style.width = (this.clientWidth * len) + 'px';
        for (var i = 0; i < len; i++) {
            lis[i].style.width = this.clientWidth + 'px';
        }
    },

    //初始化
    init:function(){
        var self = this;     //this指slider物件
        self.initStyle();
        if(!!self.touch) {
            document.getElementById('sliderWrapper').addEventListener('touchstart', self.events);
        }    //addEventListener第二個引數可以傳一個物件,會呼叫該物件的handleEvent屬性
    }
};

slider.init();