以下是基于小程序wux框架中refresh组件拓展的小程序滚动切换页码组件。
用法

<page-list  id="wux-refresher" elid="biddingList" isShowPage="{{false}}" bind:scrollbot="scrollbot"  bind:refresh="onRefresh"><template is="biddingList" data='{{biddingList}}'></template>   <!--列表dom--></page-list>

id=“wux-refresher” 获取组件上下文
elid=“biddingList”
isShowPage="{{false}}" 是否显示页码
bind:scrollbot=“scrollbot” 触底加载
bind:refresh=“onRefresh” 上拉刷新

wxml


<scroll-view class="scroll-view" id="{{elid}}" scroll-y="{{true}}"  bindscrolltolower="scrollbot"  bindscroll="scroll" bindtouchstart="bindtouchstart" bindtouchmove="bindtouchmove" bindtouchend="bindtouchend"> <view style="{{ style }}" ><view class="{{ classes.wrap }}"><view class="{{ classes.content }}"><view class="{{ classes.iconPulling }}"><text class="{{ classes.pIcon }}"></text></view><view class="{{ classes.textPulling }}">{{ pullingText }}</view><view class="{{ classes.iconRefreshing }}"><text class="{{ classes.rIcon }}"></text></view><view class="{{ classes.textRefreshing }}">{{ refreshingText }}</view></view></view><slot></slot><view class="{{ classes.lWrap }}"><view class="{{ classes.lContent }}"><text wx:if="{{noData === false}}" class="{{ classes.rIcon }}"></text><text class="wux-loader__text-loading" wx:if="{{noData === false && isShowLoadingText === true}}">{{loadingText}}</text><view wx:if="{{noData === true}}">{{loadNoDataText}}</view></view></view></view>
</scroll-view>
<view wx:if="{{isShowPage}}" style="text-align:center;">{{currentPage}}</view>

js

// componets/list/list.js
import computedBehavior from '../helpers/computedBehavior';
import classNames from '../helpers/classNames';
const defaultStyle = 'transition: transform .4s; transform: translate3d(0px, 0px, 0px) scale(1);'
Component({behaviors: [computedBehavior],options: {multipleSlots: true // 在组件定义时的选项中启用多slot支持},/*** 组件的属性列表*/properties: {elid:{type:String,value:''},   //元素idisShowPage:{type:Boolean,value:false},isEnd:{type:Boolean,value:false},list:{type:Array,value:[]},scrollTop:{type:Number,value:0},prefixCls: {type: String,value: 'wux-refresher',},pullingIcon: {type: String,value: '',},pullingText: {type: String,value: '下拉刷新',},refreshingIcon: {type: String,value: '',},refreshingText: {type: String,value: '正在刷新',},disablePullingRotation: {type: Boolean,value: false,},distance: {type: Number,value: 30,},prefixLCls: {type: String,value: 'wux-loader'},isShowLoadingText: {type: Boolean,value: false},loadingText: {type: String,value: '正在加载'},loadNoDataText: {type: String,value: '没有更多数据'},},/*** 组件的初始数据*/data: {currentPage:1,//展示的页码pageInfoList:{},initPageInfoList:{},//记录初始时第一页的数据pageInfoListCount:1,//有多少条元素scrollTop:0,/**下拉刷新相关 */style: defaultStyle,visible: false,active: false,refreshing: false,tail: false,lVisible: false,noData: false, // 是否没有更多数据windowHeight: 0,  // 窗口高度newContentHeight: 0,  // 新节点内容高度oldContentHeight: 0,   // 旧节点内容高度loading: false,   // 判断是否正在加载},computed: {classes() {const {prefixCls,pullingText,pullingIcon,disablePullingRotation,refreshingText,refreshingIcon,visible,active,refreshing,tail,prefixLCls,loading,noData,} = this.dataconst wrap = classNames(prefixCls, {[`${prefixCls}--hidden`]: !visible,[`${prefixCls}--visible`]: visible,[`${prefixCls}--active`]: active,[`${prefixCls}--refreshing`]: refreshing,[`${prefixCls}--refreshing-tail`]: tail,})  //如果是true则className push入classNamesconst content = classNames(`${prefixCls}__content`, {[`${prefixCls}__content--text`]: pullingText || refreshingText,})const iconPulling = classNames(`${prefixCls}__icon-pulling`, {[`${prefixCls}__icon-pulling--disabled`]: disablePullingRotation,})const textPulling = `${prefixCls}__text-pulling`const iconRefreshing = `${prefixCls}__icon-refreshing`const textRefreshing = `${prefixCls}__text-refreshing`const pIcon = pullingIcon || `${prefixCls}__icon--arrow-down`const rIcon = refreshingIcon || `${prefixCls}__icon--refresher`const lWrap = classNames(prefixLCls, {[`${prefixLCls}--hidden`]: !loading,[`${prefixLCls}--visible`]: loading,[`${prefixLCls}--end`]: noData,})const lContent = `${prefixLCls}__content`//console.log('vies',this.data.visible)return {wrap,content,iconPulling,textPulling,iconRefreshing,textRefreshing,pIcon,rIcon,lWrap,lContent,}},},/*** 组件的方法列表*/methods: {_pageDataFormate: function(page,top,height){let obj = {};obj[page] = { scrollTop: top, scrollBottom: top + height, height: height };return obj},/*** 滑动到底部触发*/scrollbot:function(e){// if (this.data.isEnd) return false;let that = thislet view = wx.createSelectorQuery().in(this);//console.log('scrollbot count',this.data.pageInfoListCount)if (!this.data.loading){view.select("#"+this.data.elid).fields({scrollOffset: true},function(rect){let pageInfoList = that.data.pageInfoList;//当前页面有多少个元素,即多少页let pageInfoListCount = Object.keys(pageInfoList).length//记录上一页的bottom就是当前页的toppageInfoList[pageInfoListCount].scrollBottom = rect.scrollTop;//重新计算每一页的高度let height = pageInfoList[pageInfoListCount].scrollBottom - pageInfoList[pageInfoListCount].scrollTop;//构造当前页的数据let pageInfo = that._pageDataFormate(pageInfoListCount + 1,rect.scrollTop,height)//合并页Object.assign(pageInfoList,pageInfo);that.setData({pageInfoList,pageInfoListCount: Object.keys(pageInfoList).length})}).exec()// console.log(this.data.pageInfoList)this.setData({loading: true,refreshing: false,//oldContentHeight: newContentHeight})//this.triggerEvent('loadmore')this.triggerEvent('scrollbot');}},/*** 滑动时触发主要改变页码*/scroll:function(e){//if (e.detail.scrollTop<0) return;//console.log('scroll',e.detail.scrollTop)let pageInfoList = this.data.pageInfoList;let scrollTop = e.detail.scrollTop;let currentPage = this.data.currentPage;let pageInfoListCount = this.data.pageInfoListCount;//  console.log('scrollTop',scrollTop);// console.log('scroll  count', pageInfoListCount)//判断如果当前只有一页则跳过if (pageInfoListCount == 1) return false;//如果当前滑动top大于当前页的bottom,则页码加一if (pageInfoList[currentPage] && scrollTop > pageInfoList[currentPage].scrollBottom){currentPage = (currentPage + 1) > pageInfoListCount ? pageInfoListCount : currentPage + 1this.setData({currentPage: currentPage,//scrollTop: scrollTop})} //如果当前滑动top少于当前页的top,则页码减一else if (pageInfoList[currentPage] && currentPage > 1 && scrollTop < pageInfoList[currentPage].scrollTop ) {this.setData({currentPage: currentPage - 1,//scrollTop: scrollTop})}},/****************下拉刷新功能************************ *//*** 显示*/activate() {this.setData({style: defaultStyle,visible: true,})},/*** 隐藏*/deactivate() {if (this.activated) this.activated = falsethis.setData({style: defaultStyle,visible: false,active: false,refreshing: false,tail: false,})},/*** 正在刷新*/refreshing() {this.setData({style: 'transition: transform .4s; transform: translate3d(0, 60px, 0) scale(1);',visible: true,active: true,refreshing: true,// 刷新时重新初始化加载状态loading: false,noData: false,newContentHeight: 0,oldContentHeight: 0,lVisible: false,})},/*** 刷新后隐藏动画*/tail() {this.setData({visible: true,active: true,refreshing: true,tail: true,})},/*** 加载后隐藏动画*/hide() {this.setData({lVisible: false,})},/*** 正在下拉* @param {Number} diffY 距离*/move(diffY) {const style = `transition-duration: 0s; transform: translate3d(0, ${diffY}px, 0) scale(1);`const className = diffY < this.data.distance ? 'visible' : 'active'this.setData({style,[className]: true,})},/*** 判断是否正在刷新*/isRefreshing() {return this.data.refreshing},/*** 判断是否正在加载*/isLoading() {return this.data.loading},/*** 获取触摸点坐标*/getTouchPosition(e) {return {x: e.changedTouches[0].pageX,y: e.changedTouches[0].pageY,}},/*** 创建定时器*/requestAnimationFrame(callback) {let currTime = new Date().getTime()let timeToCall = Math.max(0, 16 - (currTime - this.lastTime))let timeout = setTimeout(() => {callback.bind(this)(currTime + timeToCall)}, timeToCall)this.lastTime = currTime + timeToCallreturn timeout},/*** 清空定时器*/cancelAnimationFrame(timeout) {clearTimeout(timeout)},/*** 下拉刷新完成后的函数*/finishPullToRefresh() {this.setData({pageInfoList:this.data.initPageInfoList,})setTimeout(() => {this.requestAnimationFrame(this.tail)setTimeout(() => this.deactivate(), 200)}, 200)},/*** 上拉加载完成后的函数*/finishLoadmore(bool) {if (bool === true) {setTimeout(() => {this.setData({noData: true,loading: false,})}, 200)} else {setTimeout(() => {this.setData({loading: false})this.requestAnimationFrame(this.hide)setTimeout(() => this.deactivate(), 200)}, 200)}},/*** 手指触摸动作开始*/bindtouchstart(e) {// console.log('tt', this.isRefreshing() || this.isLoading())if (this.isRefreshing() || this.isLoading()  ) return falseconst p = this.getTouchPosition(e)this.start = pthis.diffX = this.diffY = 0this.activate()},/*** 手指触摸后移动*/bindtouchmove(e) {// console.log('tet', this.isRefreshing() || this.isLoading())if (!this.start || this.isRefreshing() || this.isLoading() ) return falseconst p = this.getTouchPosition(e)this.diffX = p.x - this.start.xthis.diffY = p.y - this.start.y// console.log(this.diffY);if (this.diffY < 0) {return false;}this.diffY = Math.pow(this.diffY, 0.8);//  console.log(this.diffY);if (!this.activated && this.diffY > this.data.distance) {this.activated = truethis.triggerEvent('pulling')} else if (this.activated && this.diffY < this.data.distance) {this.activated = false}this.move(this.diffY)},/***    手指触摸动作结束*/bindtouchend(e) {this.start = falseif (this.diffY <= 0 || this.isRefreshing() || this.isLoading()) return false//   console.log(this.diffY,'dd')this.deactivate()if (Math.abs(this.diffY) >= this.data.distance) {this.refreshing()this.triggerEvent('refresh')}},},/*** 生命周期*/lifetimes: {created() {this.lastTime = 0this.activated = false},attached() {let that = thiswx.getSystemInfo({success: function (res) {that.setData({windowHeight: res.windowHeight})}});},/*** 初始化列表高度*/ready() {let that = this;let query = wx.createSelectorQuery().in(this);//初始时紧选区页面范围的节点,不会选取任何自定义组件中的组件let id = "#" + this.data.elidquery.select(id).boundingClientRect(function (rect) {let pageInfoList = that._pageDataFormate(1, 0,rect.height);that.setData({pageInfoList,initPageInfoList:pageInfoList,})}).exec();},},
})

wxss

/*@import "../../colorui/main.wxss";
@import "../../colorui/icon.wxss";*/
.scroll-view{width: 100%;height: 100%;/*动态高度*/
}.wux-refresher {position: absolute;top: -120rpx;right: 0;left: 0;overflow: hidden;margin: auto;height: 100rpx
}
.wux-refresher--hidden {visibility: hidden
}
.wux-refresher--visible {visibility: visible
}
.wux-refresher__content {position: absolute;bottom: 10rpx;left: 0;width: 100%;color: #666;text-align: center;font-size: 60rpx
}
.wux-refresher__content--text {bottom: 0
}
.wux-refresher__text-pulling {font-size: 32rpx;line-height: 32rpx
}
.wux-refresher__text-refreshing {font-size: 32rpx;line-height: 32rpx;display: none
}
.wux-refresher__icon-pulling {width: 100%;-webkit-backface-visibility: hidden;backface-visibility: hidden;transform-style: preserve-3d;padding: 14rpx 0;animation-name: refresh-spin-back;animation-duration: .2s;animation-timing-function: linear;animation-fill-mode: none;transform: translateZ(0) rotate(0)
}
.wux-refresher__icon-refreshing {width: 100%;-webkit-backface-visibility: hidden;backface-visibility: hidden;transform-style: preserve-3d;padding: 14rpx 0;display: none;animation-duration: 1.5s
}
.wux-refresher__icon--arrow-down {display: block;margin: 0 auto;width: 40rpx;height: 40rpx;background-repeat: no-repeat;background-position: center center;background-size: 40rpx 40rpx;background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAQAAAAAYLlVAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAHdElNRQfhAhQABBG6qxTZAAABVklEQVRo3u3YvUoDQRiF4ePPTZgbEGsh23sBgqWCKQe8AVvB0tJySgPah9T2CaSxkNhY6i3YaRN1J7uz+31nAmnOVJNkM++zCcyyC2hobHnslHw5HOIZA3zgJL6xa+wX8ZcAgAGW/InsFgE2MAQQQAABBBBAAAEEEEAAAQQQYOuAjtvzcIprfOImvpYEwhFucYC7OGn/PHtfH87xuJpWcZ455vt3FjPrhCFmq+lFfGo7Iv8X3P/NZmFInv1/vr6eEfBVm1OEJJ+uZwJcJa/chLX8+nr9gDjFiCc08qM49f4CiGOW0JIf547t3Ac4giffuxH5Cb68YSf0Ebx501ZsJ/jzxmuBjcDkzRejfgKXdz2sDpd4SN6oasmKyzufljcIuWHOA3sewOLl+B1nm8w7ASaCK+8G9BKceQLQSXDnKUCWQORJQCuBytOABoHMFwASAp3X0AB+AFVjfoii8X5lAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTAyLTIwVDAwOjA0OjE3KzA4OjAwenpBPAAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wMi0yMFQwMDowNDoxNyswODowMAsn+YAAAAAASUVORK5CYII=)
}
.wux-refresher__icon--refresher {display: block;margin: 0 auto;width: 40rpx;height: 40rpx;background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%236c6c6c'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");background-repeat: no-repeat;background-position: 50%;background-size: 100%;transform-origin: 50%;animation: refresh-spin-rotate 1s steps(12,end) infinite
}
.wux-refresher--active.wux-refresher--refreshing {transition: transform .2s;transform: scale(1)
}
.wux-refresher--active.wux-refresher--refreshing .wux-refresher__icon-pulling,
.wux-refresher--active.wux-refresher--refreshing .wux-refresher__text-pulling {display: none
}
.wux-refresher--active.wux-refresher--refreshing .wux-refresher__icon-refreshing,
.wux-refresher--active.wux-refresher--refreshing .wux-refresher__text-refreshing {display: block
}
.wux-refresher--active.wux-refresher--refreshing .wux-refresher--refreshing-tail {transform: scale(0)
}
.wux-refresher--active .wux-refresher__icon-pulling:not(.wux-refresher__icon-pulling--disabled) {animation-name: refresh-spin;transform: translateZ(0) rotate(-180deg)
}
.wux-loader {overflow: hidden;margin: auto;height: 100rpx;font-size: 30rpx;position: relative;text-align: center;display: none
}
.wux-loader .wux-refresher__icon--refresher {display: inline-block;margin: 0
}
.wux-loader__text-loading {margin-left: 10rpx
}
.wux-loader--hidden {visibility: hidden;display: none
}
.wux-loader--visible {visibility: visible;display: block
}
.wux-loader--end {visibility: visible;display: block
}
.wux-loader__content {position: absolute;width: 100%;top: 50%;transform: translateY(-50%);color: #666;display: -ms-flexbox;display: flex;-ms-flex-align: center;align-items: center;-ms-flex-pack: center;justify-content: center
}
@keyframes refresh-spin {0% {transform: translateZ(0) rotate(0)}to {transform: translateZ(0) rotate(180deg)}
}
@keyframes refresh-spin-back {0% {transform: translateZ(0) rotate(180deg)}to {transform: translateZ(0) rotate(0)}
}
@keyframes refresh-spin-rotate {100% {transform: rotate(360deg)}
}

小程序滚动切换页码组件相关推荐

  1. 微信小程序常用视图容器组件

    微信小程序常用视图容器组件 1.组件概述 2.常用的试图容器组件 2.1 view 2.1.1 案例 2.2 scroll-view 2.2.1 案例 2.3 swiper 2.3.1 案例 1.组件 ...

  2. 微信小程序10:WXML 组件- 轮播图 swiper

    微信小程序10:WXML 组件- 轮播图 swiper 官网地址https://developers.weixin.qq.com/miniprogram/dev/component/swiper.ht ...

  3. 小程序scroll-view,滚动到最低_小程序滚动到底部

    小程序scroll-view,滚动到最低_小程序滚动到底部 小程序滚动条,滚到最底部解决方案1 小程序滚动到底部使用Scorll-view实现方案: scrill-view:组件要固定高度. scro ...

  4. 微信小程序入门之常用组件(04)

    常见组件 重点讲解微信小程序中常见的布局组件 view,text,rich-text,button,image,navigator,icon,swiper, radio,checkbox 等 一.vi ...

  5. 微信小程序滚动播放内容

    目录 微信小程序创建项目配置底部导航栏 微信小程序滚动播放内容 微信小程序功能中心模块开发 微信小程序个人中心页面开发 微信小程序获取电话号码 微信小程序显示列表数据 微信小程序显示分页列表 微信小程 ...

  6. 1、使用colorui制作小程序滚动广告栏

    使用colorui制作小程序滚动广告栏 我们可以使用colorui组件开发小程序,能够很容易的写出广告栏. <template><view><view class=&qu ...

  7. 微信小程序下拉框插件_微信小程序下拉框组件使用方法详解

    本文实例为大家分享了微信小程序下拉框组件的使用方法,供大家参考,具体内容如下 适用场景 1.省市三级联动 2.出生日期选择 3.性别选择 4.一般性的下拉选择等 一.省市三级联动使用 注意mode = ...

  8. 微信小程序仿微信SlideView组件slide-view

    微信小程序仿微信SlideView组件. 使用 1.安装 slide-view 从小程序基础库版本 2.2.1 或以上.及开发者工具 1.02.1808300 或以上开始,小程序支持使用 npm 安装 ...

  9. 微信小程序引入骨架屏组件

    微信小程序引入骨架屏组件 参考地址:https://github.com/cytle/ma-skeleton.git 1.克隆项目 2.把项目里的组件skeleton文件复制到自己的项目里 3.复制& ...

最新文章

  1. Mysql练习题14-至少有5名直接下属的经理
  2. python中文读音ndarray-Python Numpy 控制台完全输出ndarray的实现
  3. 猎豹移动(金山网络)2015校园招聘(c++project师)
  4. C#网络类智能开关控制板实例
  5. php订阅号借权,php订阅号借权
  6. Django常用命令
  7. 我给一个团队新成员的信
  8. linux网卡配置trunk模式,centos配置单网卡为Trunk模式
  9. Frank-wolfe算法多OD对matlab实现
  10. linux修改目录的owner及group权限
  11. 公交线路换乘代码PHP,北京公共交通集团-|线路查询|公交换乘|商务班车|定制公交|公交e路通|实时公交...
  12. B+树数据库加锁历史
  13. Win10有哪些版本?有什么区别?如何选择Win10版本
  14. item_search_img - 按图搜索义乌购商品(拍立淘)
  15. Resources Root目录和Sources Root目录的区别
  16. GIS——地图比例尺
  17. 均值-方差模型实现及应用_python_数据分析_9
  18. 软件工程结对开发——返回一个整数数组中最大子数组的和(JAVA)
  19. 可以检测手机帧率和温度的软件_拯救者电竞手机Pro评测:不只是一台手机,更是游戏主机...
  20. 聊聊心理学专业去用户体验研究方向的求职

热门文章

  1. JAVA和SQL中时间的格式化 (yyyy-MM-dd HH:mm:ss转换规则)知识总结
  2. ScyllaDB安装
  3. 大焕视界:乡愁是一道深不可测的陷阱
  4. 树莓派64位系统bullseye如何成功安装Qt5
  5. 物联网毕设选题 stm32车牌识别系统设计与实现 - 嵌入式 单片机
  6. anaconda中安装PIV库
  7. java获取视频首帧图片用于界面展示
  8. 密歇根安娜堡大学的计算机科学教授,密歇根大学安娜堡分校计算机科学与工程研究生offer及申请要求...
  9. 远程桌面连接管理器RDCMan教程
  10. statsmodels.tsa.seasonal.seasonal_decompose使用移动平均线进行季节性分解