vue 父页面中含子页面滑动,滑动结束,底部组件进行滑动

Posted jiayeyuan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue 父页面中含子页面滑动,滑动结束,底部组件进行滑动相关的知识,希望对你有一定的参考价值。

 

详见效果地址: https://pan.baidu.com/s/1Yin2q0Fh_6AQJTlbie7QMw 

技术分享图片

 

使用

1.v-touch 实现滑动效果,父级页面滑动,当父级含有子页面需要滑动功能hasClass("sm_img"),需要判断是否继续父级滑动,有的话子页面先滑动,通过upB去判断
if($(imgShowChild[that.childNum]).children().children().hasClass("sm_img")&&that.upB !=3)
2.当滑动结束后,底部组件向上滑,通过加入一个蒙版显示隐藏,使滑动事件失效, main.js引入上下滑动的自定义指令,
滑动事件在微信浏览器中有兼容问题,我是通过
使用监听window滑动事件,兼容浏览器下滑事件
 
mounted(){          

          //使用监听window滑动事件,兼容浏览器下滑事件
          window.addEventListener(‘scroll‘,this.handleScroll)
 },

 

methods: {
           handleScroll(e){
                console.log(e)
                $(".menban").hide()
        },
          vuetouch:function(s,e){
            this.name="下滑";
            $(".menban").hide()
       },
}

 

<!--如果到底部增加一个蒙版,使滑动事件失效,判断是否下滑,滑动事件可以使用-->
            <div class="menban" :style="setHeight" v-swipedown="{fn:vuetouch}" >                
                <!--{{name}}-->
            </div>

 



vue样式

<template>
    <div class="index_home">
        <v-head></v-head>
        <div class="page_com" :style="setHeight">
            <v-touch class="bannerBox" v-on:swipeup="upM(childNum)" v-on:swipedown="downM(childNum)">
                <ul class="conBox">
                    <li>
                        <div class="layered">
                            <img src="../../../static/img/index_home/section1-bg.png"  :style="setHeight"/>
                            <p class="text"> 
                                <span class="title">我们慢慢长大<br />他们渐渐老去</span>
                                <span class="turnDown" @click="toNext()">>></span>
                            </p>
                        </div>
                    </li>
                    <li :style="setChildH">
                        <div class="layered page2">
                            <img src="../../../static/img/index_home/section2-bg.png"  :style="setChildH"/>
                            <p class="text"> 
                                <span class="title">关爱,实时在线</span>
                                <span class="con">实时远程查看老人健康数据<br />定期接收健康报告</span>
                            </p>
                            <v-touch v-on:swipeup="up(0,upB)" v-on:swipedown="down(0,upB)" class="sm_img">
                                <ul class="showChlid" >
                                    <li>
                                        <img src="../../../static/img/index_home/section2-1.png" class=""/>
                                        <img src="../../../static/img/index_home/section2-text.png" class="next_page" @click="goto(‘watchPage‘,‘monitoringData‘)"/>
                                    </li>
                                    <li>
                                            <img src="../../../static/img/index_home/section2-2.png" class=""/>
                                            <img src="../../../static/img/index_home/section2-text.png" class="next_page"/>
                                    </li>
                                    <li>
                                        <img src="../../../static/img/index_home/section2-3.png" class=""/>
                                            <img src="../../../static/img/index_home/section2-text.png" class="next_page" @click="goto(‘healthy‘,‘monitoringData‘)"/>
                                    </li>
                                </ul>
                            </v-touch>
                        </div>
                    </li>
                    <li  :style="setChildH">
                        <div class="layered">
                            <img src="../../../static/img/index_home/section3-bg.png"  :style="setChildH"/>
                            <p class="text"> 
                                <span class="title">中国式亲情<br />报喜不报忧</span>
                                <span class="turnDown"  @click="toNext(index)">>></span>
                            </p>
                        </div>
                    </li>
            <!--……此处省略n个li-->

</ul> </v-touch> <!--如果到底部增加一个蒙版,使滑动事件失效,判断是否下滑,滑动事件可以使用--> <div class="menban" :style="setHeight" v-swipedown="{fn:vuetouch}" > <!--{{name}}--> </div> </div> <v-foot></v-foot> </div> </template> <script> import vHead from ‘../common/header.vue‘; import vFoot from ‘../common/footer.vue‘; export default { data(){ return{ setHeight:{ width:‘10rem‘, height:"100px" }, setConM:{ height:‘‘, }, setChildH:{ height:‘‘, }, current:0, isLast:0, isShowChlid:1, upB :0, currentIndex:0, childIndex:0, upB1:0, upB2:0, upB3:0, childNum:0, clientHeight:‘‘, name:"开始", } }, watch:{ current(oldValue,newValue){ console.log("oldValue:"+oldValue) console.log("newValue:"+newValue) if(newValue==0||newValue == 2 || newValue == 4||newValue==6){ this.isShowChlid =0; this.upB=0; }else if(newValue==1||newValue == 3 || newValue == 5||newValue==7){ this.isShowChlid =1; } } }, beforeCreate:function(){ let arr = [{name:‘首页‘,path:‘/‘}] arr = JSON.stringify(arr) localStorage.setItem(‘footListName‘,arr) }, mounted(){ // 获取浏览器可视区域高度 this.clientHeight = `${document.documentElement.clientHeight}` //document.body.clientWidth; console.log(this.clientHeight - 48); this.setHeight.height = this.clientHeight - 48 +"px" this.setConM.height = this.clientHeight - 48 +"px" this.setChildH.height = this.clientHeight+"px"; //使用监听window滑动事件,兼容浏览器下滑事件 window.addEventListener(‘scroll‘,this.handleScroll) }, methods: { handleScroll(e){ console.log(e) $(".menban").hide() }, vuetouch:function(s,e){ this.name="下滑"; $(".menban").hide() }, onChange(index) { var that = this; this.current = index; console.log(this.current) console.log("滑动了"); that.upB=0; var showChild = $(".sm_img")[that.childIndex]; var showChildUl = showChild.querySelector("ul") showChildUl.style.transform = "translateY(-" +350 * that.upB + "px)"; // if(index==1||index == 3||index == 5||index ==7){ // this.isShowChlid = 0; // } }, upM:function(index){ var that = this; // console.log("大box上滑了,加一") var conM = $(".bannerBox")[0] var imgShowChild = $(".conBox>li") // console.log(imgShowChild) // console.log(that.childNum) if(that.childNum ==7){ that.childNum =7; }else{ //判断上滑条件,如有子页面图片,不允许上滑,如果子页面滑动最后一页时,父页面进行滑动同时,子页面的位置回归原位, // console.log("判断上滑条件") if($(imgShowChild[that.childNum]).children().children().hasClass("sm_img")&&that.upB !=3){ // console.log(that.upB) }else{ that.childNum = that.childNum+1;
             $(imgShowChild[that.childNum]).addClass("show").siblings().removeClass("show") conM.style.transform = "translateY(-" +this.clientHeight * that.childNum + "px)"; that.upB = 0; } } }, downM:function(index){ var that = this; // console.log("大box下滑了,减一") var conM = $(".bannerBox")[0] var imgShowChild = $(".conBox>li") // console.log(imgShowChild) // console.log(that.childNum) if(that.childNum ==0){ that.childNum =0; }else{ //判断下滑条件,如有子页面图片,不允许上滑,如果子页面滑动最后一页时,父页面进行滑动同时,子页面的位置回归原位, // console.log(that.upB); if($(imgShowChild[that.childNum]).children().children().hasClass("sm_img")&& that.upB != -1){ // console.log("没到顶,不能滑") // console.log(that.upB) }else{ // console.log("哟,到顶呢") that.childNum = that.childNum-1; $(imgShowChild[that.childNum]).addClass("show").siblings().removeClass("show") conM.style.transform = "translateY(-" +this.clientHeight * that.childNum + "px)"; } } }, up:function(index,val){ this.isShowChlid = 0; // console.log(index) var that = this; var showChild = $(".sm_img")[index]; var showChildUl = showChild.querySelector("ul") // console.log($(showChildUl).find("li").length) if(that.upB < 3 && 0 <= that.upB){ $(".menban").hide() this.isShowChlid = 0; that.upB = val+1; showChildUl.style.transform = "translateY(-" +350 * that.upB + "px)"; } if(that.upB == 3){ // that.upB = 0 if(that.childNum == 7){ showChildUl.style.transform = "translateY(-" +350 * 2 + "px)"; $(".menban").show() } if(that.childNum != 7){ $(".menban").hide() showChildUl.style.transform = "translateY(-" +350 * 0 + "px)"; } } // console.log(that.upB) // console.log("上滑") }, down:function(index,val){ $(".menban").hide() this.isShowChlid = 0; // console.log(index) var that = this; that.childIndex = index; // that.upB = val-1; var showChild = $(".sm_img")[index]; var showChildUl = showChild.querySelector("ul") // console.log("down"+val) console.log(that.upB <= 3 && -1 < that.upB) if(that.upB == 0){ // console.log("下滑到头了") that.upB = val-1; this.isShowChlid = 1; }else if(that.upB <= 3 && 0 < that.upB){ this.isShowChlid = 0; //由于增加了一个upB的最大值,所以需要考虑到下标的不同情况(3和-1都是为了判断子页是否滑完了做的判断) if(that.childNum == 7 && that.upB == 3){ that.upB = val-2; showChildUl.style.transform = "translateY(-" +350 * that.upB + "px)"; }else{ that.upB = val-1; showChildUl.style.transform = "translateY(-" +350 * that.upB + "px)"; } // console.log(that.upB) } if(that.upB == -1){ showChildUl.style.transform = "translateY(-" +350 * 0 + "px)"; } // console.log("下滑") }, handleTouchStart(e){ console.log(e) }, handleTouchStart(e){ console.log(e) }, handleTouchStart(e){ console.log(e) }, goto(page,selectId){ var path = page; var selectId = selectId; localStorage.setItem("toId",selectId); this.$router.push({path: path}); }, toNext(index){ console.log(this.current); this.$refs.swipeH.swipeTo(this.current+1) } }, components:{ vHead, vFoot }, destroyed(){ // localStorage.setItem("toId",‘‘) // window.removeEventListener(‘scroll‘, this.handleScroll) } } </script> <style> @import "../../../static/css/index_home/index_home.css"; </style> <style type="text/css"> .index_home .van-swipe{ /*height: 300px;*/ } .index_home .van-swipe-item{ overflow: hidden; } .index_home .van-swipe-item img{ overflow: hidden; position: relative; top: 0; left: 0; } </style>

 

css样式

.index_home{
    overflow: hidden;
}
/*蒙版的样式设置*/
.index_home .menban{
    position: absolute;
    z-index: 999;
    bottom: 0;
    display: none;
}

.index_home .bannerBox{
    width: 10rem;
    /*overflow: hidden;*/
}
.index_home .page_com{
    overflow: hidden;
}
.index_home .page_com .layered{
    width: 10rem;
    position: relative;
    /*overflow: hidden;*/
}
.index_home .page_com .layered img{
    width: 100%;
    height: 100%;
}
.index_home .layered .text{
    position: absolute;
    top: 30%;
    color:#fff;
    width: 100%;
    font-size: 25px;
    line-height: 45px;
    text-align: center;    
    /*opacity: 0;*/
    transform: translate(0,50px);
    /* transition: opacity 4s, transform 1.5s 1.7s;*/
}
.index_home .show .layered .text{
    animation:myfirst 2s;
    opacity: 1;
    transform: translate(0,0);
    
}
.index_home .layered.page2 .text{
    line-height: 30px;
}
.index_home .layered .text span{
    color: #fff;
}
.index_home .layered.black_text .text span{
    color: #1E1E1E;
}
.index_home .layered.black_text .text .title span{
    font-size: 35px;
}

.index_home .layered.page2 .text {
    top: 90px;
}
.index_home .layered .con{
    display: block;
    font-size: 14px;
    line-height: 20px;
    margin-top: 10px;
}
.index_home .conBox li .layered.page2>.child_img{
    position: absolute;
    z-index: 10;
    top: 0;
    left: 0;
    height: 14.6rem;
    opacity: 0;
}

.conBox li .sm_img{
    position: absolute;
    height: 350px;
    width: 355px;
    margin: 0 auto;
    top: 185px;
    left: 50%;
    margin-left: -177.5px;
    opacity: 0;
    overflow: hidden;
    z-index: 99;
}
.conBox li .show .sm_img{
    animation:myfirst 3s;
    opacity: 1;
    /*top: 0;*/
    transform: translate(0,0);
}
.sm_img .showChlid li{
    width: 100%;
    height: 350px;
    position: relative;
}
.index_home .show{
    position: relative;
}
.index_home .page2>.turnDown{
    position: absolute;
    top: 350px;
    right: 30px;
    opacity: 0;
}
.index_home .show .page2>.turnDown{
    position: absolute;
    top: 350px;
    right: 30px;
    width: auto;
    animation: myturnDown 2s ease-in-out 0 infinite alternate;
}
.index_home .show .layered.page2>.sm_img{
    animation: myfirst 2s ease-in-out 1s forwards;
}
.index_home .show .layered.page2>.child_img{
    animation: myfirst 2s ease-in-out 1s forwards;
}
.index_home .layered.page2 .next_page{
    position: absolute;
    top: 12.6rem;
    left: 50%;
    margin-left: -36px;
    width: 72px;
    height: 25px;
    z-index: 11;
    opacity: 0;
}

.index_home .show .layered.page2 .next_page{
    animation: myfirst 2s ease-in-out 2s forwards;
}
.index_home .layered.page2 .sm_img .next_page{
    top: 310px;
    margin-left: -46px;
}
.index_home .show .layered.page2 .sm_img .next_page{
    animation: myfirst 2s ease-in-out 2s forwards;
}
.index_home .layered .turnDown{
    color: #fff;
    font-weight: 100;
    display: block;
    margin-top: 94px;
    width:2rem;
    margin-left: 4rem;
    transform:  scaleX(2) rotate(90deg);
    animation: myturnDown 2s ease-in-out 2s infinite alternate;
}
.index_home .layered.page2 .turnDown{
    width: auto;
}
.index_home .layered.black_text .turnDown{
    color: #000;
}

.index_home #footer{
    /*display: none;*/
}
/*动画效果显示加上浮*/
@keyframes myfirst
{
    from {
        opacity: 0;
        transform: translate(0,50px);
    }
    to {
        opacity: 1;
        transform: translate(0,0);
    }
}

@-moz-keyframes myfirst /* Firefox */
{
    from {
        opacity: 0;
        transform: translate(0,50px);
    }
    to {
        opacity: 1;
        transform: translate(0,0);
    }
}

@-webkit-keyframes myfirst /* Safari 和 Chrome */
{
    from {
        opacity: 0;
        transform: translate(0,50px);
    }
    to {
        opacity: 1;
        transform: translate(0,0);
    }
}

@-o-keyframes myfirst /* Opera */
{
    from {
        opacity: 0;
        transform: translate(0,50px);
    }
    to {
        opacity: 1;
        transform: translate(0,0);
    }
}

/*引导下滑效果*/
@keyframes myturnDown
{
    0% {
        opacity: 1;
        transform: translate(0,0) scaleX(2) rotate(90deg);
    }
    50% {
        opacity: 1;
        transform: translate(0,10px) scaleX(2) rotate(90deg);
    }
    100% {
        opacity: 1;
        transform: translate(0,0) scaleX(2) rotate(90deg);
    }
}

@-moz-keyframes myturnDown /* Firefox */
{
    0% {
        opacity: 1;
        transform: translate(0,0) scaleX(2) rotate(90deg);
    }
    50% {
        opacity: 1;
        transform: translate(0,10px) scaleX(2) rotate(90deg);
    }
    100% {
        opacity: 1;
        transform: translate(0,0) scaleX(2) rotate(90deg);
    }
}

@-webkit-keyframes myturnDown /* Safari 和 Chrome */
{
    0% {
        opacity: 1;
        transform: translate(0,0) scaleX(2) rotate(90deg);
    }
    50% {
        opacity: 1;
        transform: translate(0,10px) scaleX(2) rotate(90deg);
    }
    100% {
        opacity: 1;
        transform: translate(0,0) scaleX(2) rotate(90deg);
    }
}

@-o-keyframes myturnDown /* Opera */
{
    0% {
        opacity: 1;
        transform: translate(0,0) scaleX(2) rotate(90deg);
    }
    50% {
        opacity: 1;
        transform: translate(0,10px) scaleX(2) rotate(90deg);
    }
    100% {
        opacity: 1;
        transform: translate(0,0) scaleX(2) rotate(90deg);
    }
}

 

import Vue from ‘vue‘
import App from ‘./App‘
import router from ‘./router‘
import Vuex from ‘vuex‘
import VueTouch from ‘vue-touch‘

//滑动事件的功能--start
function vueTouch(el,binding,type){
    var _this=this;
    this.obj=el;
    this.binding=binding;
    this.touchType=type;
    this.vueTouches={x:0,y:0};
    this.vueMoves=true;
    this.vueLeave=true;
    this.longTouch=true;
    this.vueCallBack=typeof(binding.value)=="object"?binding.value.fn:binding.value;
    this.obj.addEventListener("touchstart",function(e){
        _this.start(e);
    },false);
    this.obj.addEventListener("touchend",function(e){
        _this.end(e);
    },false);
    this.obj.addEventListener("touchmove",function(e){
        _this.move(e);
    },false);
};
vueTouch.prototype={
    start:function(e){
        this.vueMoves=true;
        this.vueLeave=true;
        this.longTouch=true;
        this.vueTouches={x:e.changedTouches[0].pageX,y:e.changedTouches[0].pageY};
        this.time=setTimeout(function(){
            if(this.vueLeave&&this.vueMoves){
                this.touchType=="longtap"&&this.vueCallBack(this.binding.value,e);
                this.longTouch=false;
            };
        }.bind(this),1000);
    },
    end:function(e){
        var disX=e.changedTouches[0].pageX-this.vueTouches.x;
        var disY=e.changedTouches[0].pageY-this.vueTouches.y;
        clearTimeout(this.time);
        if(Math.abs(disX)>10||Math.abs(disY)>100){
            this.touchType=="swipe"&&this.vueCallBack(this.binding.value,e);
            if(Math.abs(disX)>Math.abs(disY)){
                if(disX>10){
                    this.touchType=="swiperight"&&this.vueCallBack(this.binding.value,e);
                };
                if(disX<-10){
                    this.touchType=="swipeleft"&&this.vueCallBack(this.binding.value,e);
                };
            }else{
                if(disY>10){
                    this.touchType=="swipedown"&&this.vueCallBack(this.binding.value,e);
                };
                if(disY<-10){
                    this.touchType=="swipeup"&&this.vueCallBack(this.binding.value,e);
                };  
            };
        }else{
            if(this.longTouch&&this.vueMoves){
                this.touchType=="tap"&&this.vueCallBack(this.binding.value,e);
                this.vueLeave=false
            };
        };
    },
    move:function(e){
        this.vueMoves=false;
    }
};
Vue.directive("tap",{
    bind:function(el,binding){
        new vueTouch(el,binding,"tap");
    }
});
Vue.directive("swipe",{
    bind:function(el,binding){
        new vueTouch(el,binding,"swipe");
    }
});
Vue.directive("swipeleft",{
    bind:function(el,binding){
        new vueTouch(el,binding,"swipeleft");
    }
});
Vue.directive("swiperight",{
    bind:function(el,binding){
        new vueTouch(el,binding,"swiperight");
    }
});
Vue.directive("swipedown",{
    bind:function(el,binding){
        new vueTouch(el,binding,"swipedown");
    }
});
Vue.directive("swipeup",{
    bind:function(el,binding){
        new vueTouch(el,binding,"swipeup");
    }
});
Vue.directive("longtap",{
    bind:function(el,binding){
        new vueTouch(el,binding,"longtap");
    }
});
//滑动事件的功能--end

 







以上是关于vue 父页面中含子页面滑动,滑动结束,底部组件进行滑动的主要内容,如果未能解决你的问题,请参考以下文章

解决:vue 弹窗滑动 底部页面跟着滑动

Vue禁止h5页面iOS浏览器下拉bounce效果

h5向上滑动效果 最后一页向上滑动时底部显示第一张怎么回事

使用mint-ui中弹框组件与原生弹框阻止父页面不滑动方法

使用mint-ui中弹框组件与原生弹框阻止父页面不滑动方法

Vue—KeepAlive源码探究,适时清理页面缓存