123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- <template>
- <view>
- <view :class="isend?'fixedbox2' :'fixedbox'"
- :style="{'height':windowHeight + 'px','width':windowWidth + 'px','top':fixboxtop +'px','border-top-left-radius':radius,'border-top-right-radius':radius,'z-index':zIndex}"
- @touchmove="getstart" @tap="tap" @touchend="getend" ref="fixbox">
- <view class="content" :style="{'height':windowHeight + 'px'}">
- <view class="tapBoxTouchLine" v-if="showLine">
- <view class="line" :style="{'transform': `scaleY(${lineScale})`,'width':`${lineWidth}rpx`}"></view>
- </view>
- <slot />
- </view>
- </view>
- </view>
- </template>
- <script>
- /**
- * tapBox 触摸上拉组件
- * @description 触摸上拉组件,类似于高德美团上拉组件
- * @property {String} radius 左上右上圆角
- * @property {Number} minHeight 最低高度 占总屏幕高度占比
- * @property {Number} minHeight 最高高度 占总屏幕高度占比
- * @property {Number} touchHeight 允许滑动区域高度默认顶部横线高度 0为任意区域可滑动,单位rpx
- * @property {Boolean} showLine 上否显示顶部滑动线
- * @event {Function} tap 点击事件
- * @event {Function} getstart 开始滑动时触发事件
- * @event {Function} getend 滑动结束事件
- */
- export default {
- name: 'tapBox',
- data() {
- return {
- windowHeight: 0, // 屏幕高度
- windowWidth: 0, // 屏幕宽度
- firsttop: 0, // 默认高度
- fixboxtop: 0, // 实际高度
- phonetop: 200, // 默认滑动分界线 - 后面计算为最低与最高的一半
- phoneMinTop: 100, // 默认滑动分界线 - 后面计算为最低与最高的一半
- isend: false, // 触摸结束
- isfirst: true, // 手指第一次触摸
- tapboxtop: 0, // 手指距离顶部距离
- };
- },
- props: {
- // width: 120rpx;
- // transform: scaleY(0.5);
- lineScale: {
- type: Number,
- default: 1,
- },
- lineWidth: {
- type: Number,
- default: 220,
- },
- zIndex: {
- type: Number,
- default: 99,
- },
- radius: {
- type: String,
- default: '50rpx',
- },
- minHeight: {
- type: Number,
- default: 0.2,
- },
- smallHeight: {
- type: Number,
- default: 0.35,
- },
- maxHeight: {
- type: Number,
- default: 0.5,
- },
- touchHeight: {
- type: Number,
- default: 0,
- },
- showLine: {
- type: Boolean,
- default: true,
- },
- },
- mounted() {
- this.$nextTick(function() {
- this.windowWidth = uni.getSystemInfoSync().windowWidth;
- this.windowHeight = uni.getSystemInfoSync().windowHeight;
- var defaultHeight = this.windowHeight * (1 - this.minHeight);
- this.firsttop = defaultHeight;
- this.phonetop =
- (this.windowHeight * this.maxHeight - this.windowHeight * this.minHeight) / 2;
- this.phoneMinTop =
- (this.windowHeight * this.minHeight - this.windowHeight * this.smallHeight) / 2;
- this.fixboxtop = defaultHeight;
- this.$emit('currentHeight', this.windowHeight - this.fixboxtop);
- this.$emit('maxtHeight', this.windowHeight * this.maxHeight);
- });
- },
- onReady() {},
- computed: {},
- methods: {
- // 隐藏
- concealList(){
- const H_ = uni.getSystemInfoSync().windowHeight;
- this.fixboxtop = H_ - uni.upx2px(200)
- },
- tap(e) {
- // console.log(e)
- },
- getstart(e) {
- e.preventDefault();
- const {clientY , screenY } = e.touches[0];
- let Y = clientY || screenY;
- // //#ifdef MP-WEIXIN
- // Y = e.touches[0].clientY;
- // //#endif
- // //#ifndef MP-WEIXIN
- // Y = e.touches[0].screenY;
- // //#endif
- // console.log(Y)
- // 这里特殊处理 解决:在滑动框内如果存在滚动元素,则会出现滑动时滑动框和内部滚动同时滑的问题
- if (this.touchHeight !== 0) {
- if (Y - this.fixboxtop > this.touchHeight) {
- return false;
- }
- }
- this.isend = false;
- if (this.isfirst) {
- this.isfirst = false;
- this.tapboxtop = Y - this.fixboxtop;
- }
- this.fixboxtop = Y - this.tapboxtop;
- console.log('this.fixboxtop > this.firsttop = ' ,Y , this.tapboxtop)
- if (this.fixboxtop > this.firsttop) {
- if (this.fixboxtop >= this.windowHeight * (1 - this.smallHeight)) {
- this.fixboxtop = this.windowHeight * (1 - this.smallHeight);
- }
- } else {
- // 往上滑
- if (this.fixboxtop <= this.windowHeight * (1 - this.maxHeight)) {
- this.fixboxtop = this.windowHeight * (1 - this.maxHeight);
- }
- }
- this.$emit('currentHeight', this.windowHeight - this.fixboxtop);
- },
- getend() {
- this.isend = true;
- this.isfirst = true;
- //中间高度以下
- if (this.fixboxtop > this.firsttop) {
- //当超过平衡值
- if (this.fixboxtop - this.firsttop >= this.phoneMinTop) {
- this.fixboxtop = this.windowHeight * (1 - this.smallHeight);
- } else {
- this.fixboxtop = this.windowHeight * (1 - this.minHeight);
- }
- }
- //中间高度以上
- else {
- //滑动距离小于平衡值
- if (this.firsttop - this.fixboxtop <= this.phonetop) {
- this.fixboxtop = this.firsttop;
- } else {
- this.fixboxtop = this.windowHeight * (1 - this.maxHeight);
- }
- }
- this.$emit('currentHeight', this.windowHeight - this.fixboxtop);
- },
- },
- };
- </script>
- <style lang="scss" scoped>
- .tapBoxTouchLine {
- display: flex;
- align-items: center;
- justify-content: center;
- padding: 20rpx 0 30rpx;
- }
- .line {
- margin: 0px;
- vertical-align: middle;
- // border-bottom: 8rpx solid rgb(214, 215, 217);
- height: 8rpx;
- background-color: rgb(214, 215, 217);
- border-radius: 4rpx;
- // border: 4rpx;
- // border-top-color: rgb(214, 215, 217);
- // border-right-color: rgb(214, 215, 217);
- // border-left-color: rgb(214, 215, 217);
- }
- .fixedbox {
- position: fixed;
- left: 0;
- background-color: #ffffff;
- padding: 0 12px;
- }
- .fixedbox2 {
- position: fixed;
- left: 0;
- background-color: #ffffff;
- padding: 0 12px;
- transition-property: top;
- transition-duration: 0.8s;
- }
- </style>
|