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 父页面中含子页面滑动,滑动结束,底部组件进行滑动的主要内容,如果未能解决你的问题,请参考以下文章