123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- <template>
- <div
- class="yo-scroll"
- :class="{'down':(state===0),'up':(state==1),refresh:(state===2),touch:touching}"
- @touchstart="touchStart($event)"
- @touchmove="touchMove($event)"
- @touchend="touchEnd($event)"
- >
- <section class="inner" :style="{ transform: 'translate3d(0, 0px, 0)' }">
- <header class="pull-refresh">
- <!-- <slot name="pull-refresh">
- <span class="down-tip">下拉更新</span>
- <span class="up-tip">松开刷新数据</span>
- <span class="refresh-tip">加载中……</span>
- </slot> -->
- </header>
- <slot></slot>
- <footer class="load-more" v-show="!dataList.noFlag">
- <slot name="load-more">
- <span v-show="downFlag === false">上拉加载更多</span>
- <span v-show="downFlag === true">加载中……</span>
- </slot>
- </footer>
- <!-- <div class="nullData" v-show="dataList.noFlag">暂无更多数据</div> -->
- </section>
- </div>
- </template>
-
- <script>
- export default {
- props: {
- offset: { // 默认高度
- type: Number,
- default: 100
- },
- enableInfinite: { // 上拉加载
- type: Boolean,
- default: true
- },
- enableRefresh: { // 下拉刷新
- type: Boolean,
- default: false
- },
- dataList: { // 数据列表
- default: undefined,
- required: false
- },
- onRefresh: { // 加载方法
- type: Function,
- default: undefined,
- required: false
- },
- onInfinite: { // 刷新方法
- type: Function,
- default: undefined,
- require: false
- }
- },
- data () {
- return {
- top: 0,
- state: 0,
- startX: 0,
- startY: 0,
- touching: false,
- infiniteLoading: false,
- downFlag: false // 用来显示是否加载中
- }
- },
- created () {
- console.log(this.dataList)
- },
- methods: {
- touchStart (e) {
- this.startY = e.targetTouches[0].pageY
- this.startX = e.targetTouches[0].pageX
- this.startScroll = this.$el.scrollTop || 0
- this.touching = true // 留着有用,不能删除
-
- // this.dataList.noFlag = false
- // this.$el.querySelector('.load-more').style.display = 'block'
- },
- touchMove (e) {
- if (this.dataList.noFlag || !this.touching) {
- return
- }
- let diff = e.targetTouches[0].pageY - this.startY - this.startScroll
- if (diff > 0) e.preventDefault()
- this.top = Math.pow(diff, 0.8) + (this.state === 2 ? this.offset : 0)
- if (this.state === 2) { // in refreshing
- return
- }
- if (this.top >= this.offset) {
- this.state = 1
- } else {
- this.state = 0
- }
-
- let more = this.$el.querySelector('.load-more')
- if (!this.top && this.state === 0) {
- more.style.display = 'block'
- } else {
- more.style.display = 'none'
- }
- },
- touchEnd (e) {
- // if (!this.enableRefresh) {
- // return
- // }
- this.touching = false
- if (this.state === 2) { // in refreshing
- this.state = 2
- this.top = this.offset
- return
- }
- if (this.top >= this.offset) { // do refresh
- this.refresh()
- } else { // cancel refresh
- this.state = 0
- this.top = 0
- }
-
- // 用于判断滑动是否在原地 ----begin
- let endX = e.changedTouches[0].pageX
- let endY = e.changedTouches[0].pageY
- let dy = this.startY - endY
- let dx = endX - this.startX
- // 如果滑动距离太短
- if (Math.abs(dx) < 2 && Math.abs(dy) < 2) {
- // console.log("滑动距离太短")
- this.downFlag = false
- return
- }
- // --------end--------
-
- // if (!this.enableInfinite || this.infiniteLoading) {
- // return
- // }
-
- if (this.dataList.noFlag) {
- return
- }
-
- let outerHeight = this.$el.clientHeight
- let innerHeight = this.$el.querySelector('.inner').clientHeight
- let scrollTop = this.$el.scrollTop
- let ptrHeight = this.onRefresh ? this.$el.querySelector('.pull-refresh').clientHeight : 0
- let bottom = innerHeight - outerHeight - scrollTop - ptrHeight
-
- // console.log(bottom + " __ " + this.offset)
-
- if (bottom <= this.offset && this.state === 0) {
- this.downFlag = true
- this.infinite()
- } else {
- this.$el.querySelector('.load-more').style.display = 'none'
- this.downFlag = false
- }
- },
- refresh () {
- this.state = 2
- this.top = this.offset
- setTimeout(() => {
- this.onRefresh(this.refreshDone)
- }, 1000)
- },
- refreshDone () {
- this.state = 0
- this.top = 0
- },
-
- infinite () {
- this.infiniteLoading = true
-
- setTimeout(() => {
- this.onInfinite(this.infiniteDone)
- }, 2000)
- },
-
- infiniteDone () {
- this.infiniteLoading = false
- this.downFlag = false
- }
- }
- }
- </script>
-
- <style lang="scss" scoped>
- .yo-scroll {
- font-size: 0.24rem;
- position: fixed;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- overflow: auto;
- z-index: 100;
- height: auto;
- -webkit-overflow-scrolling: touch;
- .inner {
- position: absolute;
- top: -0.5rem;
- width: 100%;
- height: auto;
- transition-duration: 300ms;
- .pull-refresh {
- position: relative;
- left: 0;
- top: 0;
- width: 100%;
- height: 0.5rem;
- display: flex;
- display: -webkit-flex;
- align-items: center;
- justify-content: center;
- }
- .load-more {
- height: 0.5rem;
- line-height: 0.5rem;
- display: flex;
- text-align: center;
- align-items: center;
- justify-content: center;
- display: none;
- }
- .nullData {
- // 暂无更多数据样式
- font-size: 0.13rem;
- color: #999999;
- height: 0.5rem;
- line-height: 0.5rem;
- text-align: center;
- }
- .down-tip,
- .refresh-tip,
- .up-tip {
- display: none;
- }
- .up-tip:before,
- .refresh-tip:before {
- content: '';
- display: inline-block;
- width: 1.6rem;
- height: 0.7rem;
- background-size: 70% !important;
- position: absolute;
- top: 0;
- left: 20%;
- }
- // .up-tip:before {
- // background: url(./loading.gif) no-repeat center;
- // }
- // .refresh-tip:before {
- // background: url(./loading.gif) no-repeat center;
- // }
- }
- }
-
- .yo-scroll.touch .inner {
- transition-duration: 0;
- }
-
- .yo-scroll.down .down-tip {
- display: block;
- }
-
- .yo-scroll.up .up-tip {
- display: block;
- }
-
- .yo-scroll.refresh .refresh-tip {
- display: block;
- }
- </style>
|