移動端 局部dom實現滾動

移動端局部dom添加滑動事件

源碼


/**
 * moveTopLimit: 移動過程中,隨著手指的滑動 dom的偏移量
 * modifyTopLimit: 觸發touchEnd的時候 我們需要進行吸頂這樣的一個交互 設置吸頂的范圍
 */
export default class TouchMove {
    constructor(params) {
        this.props = params;
        this.checkParams(params);
        this.startY = 0;
        this.moveEndY = 0;
        this.oldMoveY = 0;
        this.offsetSum = 0;
        this.curDistance = 0;
        this.init();
    }
    checkParams() {
        const objectKey = [
            'Dom',
            'slider',
        ];
        const baseTypeKey = [
            'moveTopLimit',
            'moveBottomLimit',
            'modifyTopLimit',
            'modifyBottomLimit',
        ];
        objectKey.forEach((item) => {
            if (!this.props[item]) {
                throw new Error(`${item}傳參錯誤,請檢查之后重試`);
            }
        });
        baseTypeKey.forEach((item) => {
            if (this.props[item] === undefined ||
                (Object.prototype.toString.call(this.props[item]) !== '[object Number]'
                    && Object.prototype.toString.call(this.props[item]) !== '[object String]')) {
                throw new Error(`${item}傳參錯誤,請傳入數字或者字符類型的數字`);
            }
        });
    }
    init() {
        this.Dom = this.props.Dom;
        this.slider = this.props.slider;
        this.moveTopLimit = parseInt(this.props.moveTopLimit, 10) || 0;
        this.moveBottomLimit = parseInt(this.props.moveBottomLimit, 10) || 0;
        this.modifyTopLimit = parseInt(this.props.modifyTopLimit, 10) || 0;
        this.modifyBottomLimit = parseInt(this.props.modifyBottomLimit, 10) || 0;
        this.addListenerWheel();
    }
    addListenerWheel() {
        this.Dom.addEventListener('touchstart', (e) => {
            this.touchStart(e);
        });
        this.Dom.addEventListener('touchmove', (e) => {
            this.touchMove(e);
        });
        this.Dom.addEventListener('touchend', (e) => {
            this.touchEnd(e);
        });
    }
    touchStart(event) {
        this.startY = parseInt(event.touches[0].clientY, 10);
        this.oldMoveY = this.startY;
    }
    touchMove(event) {
        // 當屏幕上有多個touch或者頁面被縮放過 就不執行move操作
        if (event.targetTouches.length > 1 || (event.scale && event.scale !== 1)) return;
        event.preventDefault();
        this.moveY = event.touches[0].clientY;
        this.offset = (this.moveY - this.oldMoveY);
        // 獲取dom當前滾動值
        this.getCurDistance();
        this.offsetSum = this.offset + this.curDistance;
        // 設置滑動范圍
        if (this.offsetSum > 0) {
            this.offsetSum = Math.min(this.offsetSum, this.moveTopLimit);
        } else if (this.offsetSum < 0) {
            this.offsetSum = Math.max(this.offsetSum, this.moveBottomLimit);
        }
        this.oldMoveY = this.moveY;
        this.movePosition(this.offsetSum);
    }
    touchEnd(event) {
        this.moveEndY = parseInt(event.changedTouches[0].clientY, 10);
        this.offset = (this.moveEndY - this.startY);
        this.getCurDistance();
        this.offsetSum = this.offset + this.curDistance;
        this.movePosition(this.offsetSum, 'end');
        // 修正位置 回彈效果
        this.modifyPosition(this.offsetSum);
    }
    getCurDistance() {
        if (this.slider.style.transform) {
            this.curDistance = parseInt(
                this.slider.style.transform.split(',')[1], 10) || 0;
        } else {
            this.curDistance = parseInt(
                this.slider.style.webkitTransform.split(',')[1], 10) || 0;
        }
    }
    movePosition(distance) {
        this.slider.style.webkitTransform = `translate3d(0,${distance}px, 0)`;
        this.slider.style.transform = `translate3d(0,${distance}px, 0)`;
    }
    modifyPosition(distance) {
        if (distance > this.modifyTopLimit) {
            this.curDistance = this.modifyTopLimit;
            this.movePosition(this.modifyTopLimit);
        } else if (distance < this.modifyBottomLimit) {
            this.curDistance = this.modifyBottomLimit;
            this.movePosition(this.modifyBottomLimit);
        }
    }
}


如何使用

    const dom = getElementsByClassName('lose-lottery-content')[0];
            const slider = getElementsByClassName('lose-lottery-container')[0];
            const itemHeight = getElementsByClassName('lottery-item')[0].clientHeight;
            const bottomlimit =
        getElementsByClassName('lose-lottery-container')[0].clientHeight -
        getElementsByClassName('lose-lottery-content')[0].clientHeight;
            // eslint-disable-next-line no-new
            new TouchMove({
                Dom: dom,
                slider,
                moveTopLimit: itemHeight,
                moveBottomLimit: -(bottomlimit + itemHeight),
                modifyTopLimit: 0,
                modifyBottomLimit: -(bottomlimit + 20),
            });

參考鏈接

https://github.com/surmon-china/vue-awesome-swiper/issues/423

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 簡說Vue (組件庫) https://github.com/ElemeFE/element" 餓了么出品的VUE...
    Estrus丶閱讀 1,803評論 0 1
  • 基于Vue的一些資料 內容 UI組件 開發框架 實用庫 服務端 輔助工具 應用實例 Demo示例 element★...
    嘗了又嘗閱讀 1,175評論 0 1
  • 1-------- 走進前端 2-------- jQuery 3-------- CSS 4-------- A...
    依依玖玥閱讀 2,355評論 0 34
  • 時光走過了那么久,一轉眼就高三了。其實心里都明白,對于未來的定義連自己都不知道。突然就得自己竟這樣傻傻的即將度過我...
    無塵詩人閱讀 170評論 0 3
  • 姓名:張嘉令 公司:上海中英閥門管件有限公司 【日精進打卡第43天 】 【知~學習】 《六項精進》1遍共47遍 《...
    天空_62f7閱讀 85評論 0 0