滑动功能-草稿

<template>
    <div class="bsx-swipe">
        <div class="bsx-swipe-button" :style="{height}">
            <slot name="button"></slot>
        </div>
        <div class="flex1" 
            ref="content" 
            @click="hide" 
            shouldStopPropagation="true" 
            @touchstart="touchstart" 
            @touchmove="touchmove" 
            @touchend="touchend">
            <slot name="content"></slot>
        </div>
    </div>
</template>

<script>
import config from './config';
const dom=weex.requireModule('dom');
const animation=weex.requireModule('animation');

export default {
    name:'bsx-swipe',
    props:{

        /*
         * 回调额外参数
         */
        args:{
            type:Object,
            default:config.args
        }
    },
    data(){
        return {
            width:0,
            height:0,
            startX:0,
            startY:0,
            opened:false,
            isMoving:false
        }
    },
    mounted(){
        this.$nextTick(()=>{
            this.getContentSize(this.$slots.content[0].elm,size=>{
                this.height=Math.floor(size.height);
            });
            this.getContentSize(this.$slots.button[0].elm,size=>{
                this.width=size.width;
            });
        });
    },
    methods:{
        hide(){
            if(this.opened){
                this.isMoving=true;
                return new Promise((resolve,reject)=>{
                    this.scrollTo(0,300,()=>{
                        this.isMoving=false;
                        this.opened=false;
                        resolve();
                    });
                });
            };
        },
        show(){
            if(!this.opened){
                this.isMoving=true;
                return new Promise((resolve,reject)=>{
                    this.scrollTo(this.width,300,()=>{
                        this.isMoving=false;
                        this.opened=true;
                        resolve();
                    });
                });
            };
        },
        touchstart(event){
            this.startX=event.changedTouches[0].screenX;
            this.startY=event.changedTouches[0].screenY;
            this.isMoving=true;
        },
        touchmove(event){
            if(!this.isMoving||(this.startY-event.changedTouches[0].screenY>=5)){
                return this.isMoving=false;
            };
            let distance=this.startX-event.changedTouches[0].screenX;
            if(this.opened){
                distance+=this.width;
            };
            if(distance>0){
                this.scrollTo(distance,0);
            };
        },
        touchend(event){
            let targetX=this.startX-event.changedTouches[0].screenX,
                distance=0;
            if(this.opened){
                if(targetX>0){
                    distance=this.width;
                };
            }else{
                if(targetX>0&&targetX>=this.width*0.5){
                    distance=this.width;
                };
            };
            this.scrollTo(distance,distance>5?300:0,()=>{
                this.isMoving=false;
                this.opened=distance!=0;
                this.$emit('onSwiped',{
                    args:this.args,
                    status:this.opened
                });
            });
        },
        scrollTo(x,time,fn){
            this.setAnimation(this.$refs.content,{
                scrollX:x,
                duration:time,
                timingFunction:time===0?null:'ease-out',
                callback:fn
            });
        },
        setAnimation(ref,{scrollX,duration,timingFunction,callback}){
            animation.transition(ref,{
                styles:{
                    transform:`translateX(${-scrollX}px)`
                },
                duration:duration||0,
                timingFunction:timingFunction||'linear',
                needLayout:false,
                delay:0
            },()=>{
                callback&&callback();
            });
        },
    
        getContentSize(el,fn){
            let sid=setInterval(()=>next(),100);
            let next=()=>{
                dom.getComponentRect(el,res=>{
                    if(res.result){
                        fn&&fn(res.size);
                    }else{
                        next();
                    };
                });
                clearInterval(sid);
            };
        }
    }
};
</script>

<style lang="scss" scoped>
@import 'src/js/css/base.scss';
.bsx-swipe{
    background-color: #fff;
    overflow: hidden;
}
.bsx-swipe-button{
    position: absolute;
    right: 0;
    top:0;
    bottom:0;
}
</style>
  • setInterval()
    javascript方法;
    setInterval()按照指定周期不停的调用函数,直到调用clearInterval()或窗口被关闭为止;

  • getComponentRect(ref, callback)
    weex方法;
    @ref,要滚动到的那个节点。
    @callback,异步方法,通过回调返回信息。
    获取某个元素 View 的外框;

  • Math.floor()
    javascript方法;
    对数进行下舍入。

  • stopPropagation
    weex方法;
    用于内嵌处理Native滑动冲突的情况,阻止Native事件进行冒泡传递。

shouldStopPropagationInitResult 默认初始化false/true的结果
shouldStopPropagationInterval 默认数字类型,控制touch频率,减少JS和Native通信次数,提升流畅性。

转载于:https://www.jianshu.com/p/0f121625ac0a

猜你喜欢

转载自blog.csdn.net/weixin_34360651/article/details/91285524