微信小程序自定义导航的下拉刷新组件

微信小程序实现自定义导航的下拉刷新

wxml代码:


<view>
	<movable-area class="movable-area">
		<movable-view class="scroll" style="height: calc(100vh + 40rpx + {{refreshSize}}rpx)" bind:change="change" bind:touchend="touchend" direction="vertical" disabled="{{refreshStatus >= 3}}" y='{{move}}'>
			<scroll-view class="scroll__view" style="padding-top: {{topSize}}px;" scroll-y="{{refreshStatus == 1}}" bindscroll="scroll" scroll-top="{{scrollTop}}" >
			<!-- 刷新box start -->
				<view id="refresh" class="scroll__refresh " style="height:{{refreshSize}}rpx;">
					<!-- loading图start -->
					<view class="scroll__loading">
						<view class="loading" >
							<view class="loading__item"></view>
							<view class="loading__item"></view>
							<view class="loading__item"></view>
							<view class="loading__item"></view>
							<view class="loading__item"></view>
							<view class="loading__item"></view>
							<view class="loading__item"></view>
							<view class="loading__item"></view>
							<view class="loading__item"></view>
							<view class="loading__item"></view>
							<view class="loading__item"></view>
							<view class="loading__item"></view>
						</view>
						<view class="text" >加载中...</view>
					</view>
					<!-- loading图end -->
				</view>
					<!-- 刷新box end -->
				<slot></slot>
			</scroll-view>
		</movable-view>
	</movable-area>
</view>

wxss代码:

.movable-area {
  width: 100%;
  /* height:100%; */
  height: 100vh;
}

.scroll {
  width: 100%;
  height: calc(100vh + 90rpx);
}

.scroll__view {
  height: 100%;
  position: relative;
  box-sizing: border-box;
}

.scroll__refresh {
  height: 90rpx;
  position: relative;
}

.scroll__refresh--hidden {
  visibility: hidden;
}

.scroll__bottom {
  position: relative;
  height: 40rpx;
  padding: 40rpx 0;
}

.scroll__loading {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  transform: translateY(-50%);
  text-align: center;
  color: #999999;
}

.scroll__loading .text {
  display: inline-block;
  vertical-align: middle;
  margin-left: 40rpx;
}

.success {
  position: absolute;
  z-index: 9;
  top: 20rpx;
  left: 0;
  width: 100%;
  height: 70rpx;
  line-height: 70rpx;
  font-size: 24rpx;
  text-align: center;
  opacity: 0;
  transform: scale(0);
  color: #3F82FD;
}

.success:after {
  content: " ";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: currentColor;
  opacity: 0.7;
  transform: scaleX(0);
  transition: transform 0.3s ease-in-out;
  z-index: 0;
}

.success>.info {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  color: #ffffff;
}

.success--show {
  opacity: 1;
  transform: scale(1);
}

.success--show:after {
  transform: scaleX(1);
}

.success--tran {
  opacity: 0;
  transform: translateY(-100%);
  transition: opacity 0.35s linear, transform 0.35s linear;
}

.empty {
  padding: 30rpx;
  text-align: center;
}

.empty__image {
  width: 200rpx;
  height: 200rpx;
  margin: 160rpx auto 60rpx;
}

.empty__text {
  color: #999999;
}

.arrow {
  position: relative;
  border-radius: 4rpx;
  width: 4rpx;
  height: 30rpx;
  background: #a5a5a5;
  transition: transform 0.15s ease-in-out;
  display: inline-block;
  vertical-align: middle;
}

.arrow:before {
  position: absolute;
  content: "";
  bottom: -4rpx;
  right: 50%;
  width: 4rpx;
  height: 16rpx;
  transform: rotate(45deg);
  transform-origin: 100% 100%;
  background: #a5a5a5;
  border-radius: 4rpx;
}

.arrow:after {
  position: absolute;
  content: "";
  bottom: -4rpx;
  left: 50%;
  width: 4rpx;
  height: 16rpx;
  transform: rotate(-45deg);
  transform-origin: 0% 100%;
  background: #a5a5a5;
  border-radius: 4rpx;
}

.arrow.rotate {
  transform: rotate(-180deg);
}

.loading {
  position: relative;
  display: inline-block;
  vertical-align: middle;
  width: 36rpx;
  height: 36rpx;
  margin-right: -14rpx;
}

.loading__item {
  position: absolute;
  top: 0;
  left: 0;
  width: 36rpx;
  height: 36rpx;
}

.loading__item:before {
  content: "";
  display: block;
  margin: 0 auto;
  width: 4rpx;
  height: 8rpx;
  background-color: #a5a5a5;
  border-radius: 4rpx;
  animation: fadeDelay 1.2s infinite ease-in-out both;
}

.loading__item:nth-child(2) {
  transform: rotate(30deg);
}

.loading__item:nth-child(2):before {
  animation-delay: -1.1s;
}

.loading__item:nth-child(3) {
  transform: rotate(60deg);
}

.loading__item:nth-child(3):before {
  animation-delay: -1s;
}

.loading__item:nth-child(4) {
  transform: rotate(90deg);
}

.loading__item:nth-child(4):before {
  animation-delay: -0.9s;
}

.loading__item:nth-child(5) {
  transform: rotate(120deg);
}

.loading__item:nth-child(5):before {
  animation-delay: -0.8s;
}

.loading__item:nth-child(6) {
  transform: rotate(150deg);
}

.loading__item:nth-child(6):before {
  animation-delay: -0.7s;
}

.loading__item:nth-child(7) {
  transform: rotate(180deg);
}

.loading__item:nth-child(7):before {
  animation-delay: -0.6s;
}

.loading__item:nth-child(8) {
  transform: rotate(210deg);
}

.loading__item:nth-child(8):before {
  animation-delay: -0.5s;
}

.loading__item:nth-child(9) {
  transform: rotate(240deg);
}

.loading__item:nth-child(9):before {
  animation-delay: -0.4s;
}

.loading__item:nth-child(10) {
  transform: rotate(270deg);
}

.loading__item:nth-child(10):before {
  animation-delay: -0.3s;
}

.loading__item:nth-child(11) {
  transform: rotate(300deg);
}

.loading__item:nth-child(11):before {
  animation-delay: -0.2s;
}

.loading__item:nth-child(12) {
  transform: rotate(330deg);
}

.loading__item:nth-child(12):before {
  animation-delay: -0.1s;
}

@keyframes fadeDelay {

  0%,
  39%,
  100% {
    opacity: 0.2;
  }

  40% {
    opacity: 1;
  }
}

@-webkit-keyframes fadeDelay {

  0%,
  39%,
  100% {
    opacity: 0.2;
  }

  40% {
    opacity: 1;
  }
}

js代码:

Component({
	properties: {
		// 加载中
		requesting: {
			type: Boolean,
			value: false,
			observer: 'requestingEnd',
		},
		// 下拉刷新的高度
		refreshSize: {
			type: Number,
			value: 90
		},
		// 顶部高度
		topSize: {
			type: Number,
			value: 0,
		},
	
	},
	data: {
		/* 未渲染数据 */
		mode: 'refresh', // refresh 和 more 两种模式
		successShow: false, // 显示success
		refreshStatus: 1, // 1: 下拉刷新, 2: 松开更新, 3: 加载中, 4: 加载完成
		move: -100, // movable-view 偏移量
		scrollHeight1: 0, // refresh view 高度负值
		scrollHeight2: 0, // refresh view - success view 高度负值
		timer: null,
		/* 渲染数据 */
		scrollTop: 0,
	},
	methods: {

		/**
		 * movable-view 滚动监听
		 */
		change(e) {
			let refreshStatus = this.data.refreshStatus,
				diff = e.detail.y;

			if (refreshStatus >= 3) return;

			if (diff > -10) {
				this.setData({
					refreshStatus: 2
				});
			} else {
				this.setData({
					refreshStatus: 1
				});
			}
		},
		/**
		 * movable-view 触摸结束事件
		 */
		touchend() {
			let refreshStatus = this.data.refreshStatus;
			if (refreshStatus >= 3) return;
			if (refreshStatus === 2) {
				// wx.vibrateShort();
				this.setData({
					refreshStatus: 3,
					move: 0,
					mode: 'refresh'
				});
				this.triggerEvent('refresh');
			} else if (refreshStatus === 1) {
				this.setData({
					move: this.data.scrollHeight1
				});
				
			}
		},
		/**
		 * 监听 requesting 字段变化, 来处理下拉刷新对应的状态变化
		 */
		requestingEnd(newVal, oldVal) {
			// if (this.data.mode === 'more') return;
			if (oldVal === true && newVal === false) {
				setTimeout(() => {
					this.setData({
						successShow: true,
						refreshStatus: 4,
						move: this.data.scrollHeight2
					});
					setTimeout(() => {
						this.setData({
							move: this.data.scrollHeight1
						});
						setTimeout(() => {
							this.setData({
								refreshStatus: 1,
								successShow: false,
								move: this.data.scrollHeight1
							});
						}, 100)
					}, 100)
				}, 500)
			} else {
				if (this.data.refreshStatus !== 3) {
					this.setData({
						refreshStatus: 3,
						move: 0
					});
				}
			}
		},
		
		/**
		 * 初始化scroll组件参数, 动态获取 下拉刷新区域 和 success 的高度
		 */
		init() {
			let {windowWidth} = wx.getSystemInfoSync();
			let successHeight=0
			console.log(windowWidth,"successHeight")
			this.createSelectorQuery().select("#refresh").boundingClientRect((res) => {
				this.setData({
					scrollHeight1: -res.height,
					scrollHeight2: successHeight - res.height
				});
			}).exec();
		},
	},
	ready() {
		this.init();
	}
});

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值