<template>
							 | 
						|
									<view class="yingbing-scroller"
							 | 
						|
									:refreshState="refreshState" :change:refreshState="pulldownwxs.refreshStateWatcher"
							 | 
						|
									:pulldownable="pulldownable" :change:pulldownable="pulldownwxs.pulldownableWatcher"
							 | 
						|
									:pullupable="pullupable" :change:pullupable="pulldownwxs.pullupableWatcher"
							 | 
						|
									@touchstart="pulldownwxs.touchstart"
							 | 
						|
									@touchmove="pulldownwxs.touchmove"
							 | 
						|
									@touchend="pulldownwxs.touchend"
							 | 
						|
									@touchcancel="pulldownwxs.touchcancel">
							 | 
						|
										<view class="yingbing-scroller-wrapper">
							 | 
						|
											<view class="yingbing-scroller-refresh">
							 | 
						|
												<refresh-loading size="30" :visible="pulldownStatus == 'end' ? false : Boolean(pulldownStatus)" :color="loadingColor"></refresh-loading>
							 | 
						|
												<text class="yingbing-scroller-refresh-text" :style="{color: loadingColor}">{{ pulldownText }}</text>
							 | 
						|
											</view>
							 | 
						|
											<view class="yingbing-scroll">
							 | 
						|
												<scroll-view
							 | 
						|
												scroll-anchoing
							 | 
						|
												class="yingbing-scroll-view"
							 | 
						|
												scroll-y
							 | 
						|
												:refresher-enabled="false"
							 | 
						|
												:scroll-into-view="scrollIntoViewId"
							 | 
						|
												:scroll-with-animation="scrollWithAnimation"
							 | 
						|
												:show-scrollbar="false"
							 | 
						|
												:scroll-top="scrollTop"
							 | 
						|
												:lower-threshold="100"
							 | 
						|
												@scroll="handleScroll" @scrolltolower="handleScrolltolower"
							 | 
						|
												@scrolltoupper="handleScrolltoupper">
							 | 
						|
													<view :id="'yingbing-scroll-item_' + index" v-for="(item, index) in data" :key="item.index + '_' + item.current">
							 | 
						|
														<!-- #ifdef MP -->
							 | 
						|
														<slot :name="'wx:' + index"></slot>
							 | 
						|
														<!-- #endif -->
							 | 
						|
														<!-- #ifndef MP -->
							 | 
						|
														<slot :item="item" :index="index"></slot>
							 | 
						|
														<!-- #endif -->
							 | 
						|
													</view>
							 | 
						|
													<view class="yingbing-scroller-refresh" v-if="loadmoreable" @tap="handleScrolltolower">
							 | 
						|
														<refresh-loading size="30" :visible="loadmoreStatus == 'end' ? false : Boolean(loadmoreStatus)" :color="loadingColor"></refresh-loading>
							 | 
						|
														<text class="yingbing-scroller-refresh-text">{{loadmoreText}}</text>
							 | 
						|
													</view>
							 | 
						|
												</scroll-view>
							 | 
						|
											</view>
							 | 
						|
											<view class="yingbing-scroller-refresh">
							 | 
						|
												<refresh-loading size="30" :visible="pullupStatus == 'end' ? false : Boolean(pullupStatus)" :color="loadingColor"></refresh-loading>
							 | 
						|
												<text class="yingbing-scroller-refresh-text" :style="{color: loadingColor}">{{ pullupText }}</text>
							 | 
						|
											</view>
							 | 
						|
										</view>
							 | 
						|
									</view>
							 | 
						|
								</template>
							 | 
						|
								
							 | 
						|
								<script>
							 | 
						|
									import RefreshLoading from '../loading/loading.vue'
							 | 
						|
									const readyHeight = 80
							 | 
						|
									export default {
							 | 
						|
										options: {
							 | 
						|
											addGlobalClass: true,
							 | 
						|
											virtualHost: true,//将自定义节点设置成虚拟的,更加接近Vue组件的表现。我们不希望自定义组件的这个节点本身可以设置样式、响应 flex 布局等,而是希望自定义组件内部的第一层节点能够响应 flex 布局或者样式由自定义组件本身完全决定
							 | 
						|
										},
							 | 
						|
										components: {
							 | 
						|
											RefreshLoading
							 | 
						|
										},
							 | 
						|
										inject: ['getPrevChapterDefaultText', 'getNextChapterDefaultText', 'getChapterReadyText', 'getChapterLoadingText', 'getChapterSuccessText', 'getChapterFailText', 'getPrevChapterEndText', 'getNextChapterEndText'],
							 | 
						|
										props: {
							 | 
						|
											data: {
							 | 
						|
												type: Array,
							 | 
						|
												default () {
							 | 
						|
													return new Array
							 | 
						|
												}
							 | 
						|
											},
							 | 
						|
											loadingColor: {
							 | 
						|
												type: String,
							 | 
						|
												default: '#333'
							 | 
						|
											},
							 | 
						|
											autoplay: {
							 | 
						|
												type: Boolean,
							 | 
						|
												default: false
							 | 
						|
											},
							 | 
						|
											pulldownable: {
							 | 
						|
												type: Boolean,
							 | 
						|
												default: false
							 | 
						|
											},
							 | 
						|
											pullupable: {
							 | 
						|
												type: Boolean,
							 | 
						|
												default: false
							 | 
						|
											},
							 | 
						|
											loadmoreable: {
							 | 
						|
												type: Boolean,
							 | 
						|
												default: false
							 | 
						|
											}
							 | 
						|
										},
							 | 
						|
										computed: {
							 | 
						|
											chapterReadyText () {
							 | 
						|
												return this.getChapterReadyText()
							 | 
						|
											},
							 | 
						|
											chapterLoadingText () {
							 | 
						|
												return this.getChapterLoadingText()
							 | 
						|
											},
							 | 
						|
											chapterSuccessText () {
							 | 
						|
												return this.getChapterSuccessText()
							 | 
						|
											},
							 | 
						|
											chapterFailText () {
							 | 
						|
												return this.getChapterFailText()
							 | 
						|
											},
							 | 
						|
											prevChapterDefaultText () {
							 | 
						|
												return this.getPrevChapterDefaultText()
							 | 
						|
											},
							 | 
						|
											prevChapterEndText() {
							 | 
						|
												return this.getPrevChapterEndText()
							 | 
						|
											},
							 | 
						|
											nextChapterDefaultText() {
							 | 
						|
												return this.getNextChapterDefaultText()
							 | 
						|
											},
							 | 
						|
											nextChapterEndText() {
							 | 
						|
												return this.getNextChapterEndText()
							 | 
						|
											},
							 | 
						|
											pulldownText () {
							 | 
						|
												return this.pulldownStatus == 'ready' ? this.chapterReadyText : this.pulldownStatus == 'success' ? this.chapterSuccessText : this.pulldownStatus == 'fail' ? this.chapterFailText :  this.pulldownStatus == 'end' ? this.prevChapterEndText : this.prevChapterDefaultText
							 | 
						|
											},
							 | 
						|
											pullupText () {
							 | 
						|
												return this.pullupStatus == 'ready' ? this.chapterReadyText : this.pullupStatus == 'success' ? this.chapterSuccessText : this.pullupStatus == 'fail' ? this.chapterFailText :  this.pullupStatus == 'end' ? this.nextChapterEndText : this.nextChapterDefaultText
							 | 
						|
											},
							 | 
						|
											loadmoreText () {
							 | 
						|
												return this.loadmoreStatus == 'ready' ? this.chapterLoadingText : this.loadmoreStatus == 'success' ? this.chapterSuccessText : this.loadmoreStatus == 'fail' ? this.chapterFailText :  this.loadmoreStatus == 'end' ? this.nextChapterEndText : this.nextChapterDefaultText
							 | 
						|
											}
							 | 
						|
										},
							 | 
						|
										data () {
							 | 
						|
											return {
							 | 
						|
												refreshState: '',
							 | 
						|
												pulldownStatus: '',
							 | 
						|
												pullupStatus: '',
							 | 
						|
												loadmoreStatus: '',
							 | 
						|
												isLoadmore: false,
							 | 
						|
												scrollIntoViewId: '',
							 | 
						|
												scrollWithAnimation: false,
							 | 
						|
												scrollTop: 0,
							 | 
						|
												scrollTopRecord: 0
							 | 
						|
											}
							 | 
						|
										},
							 | 
						|
										created() {
							 | 
						|
											this.startAutoplay()
							 | 
						|
										},
							 | 
						|
										beforeDestroy() {
							 | 
						|
											this.stopAutoplay()
							 | 
						|
										},
							 | 
						|
										methods: {
							 | 
						|
											handleScroll (e) {
							 | 
						|
												this.scrollTopRecord = e.detail.scrollTop
							 | 
						|
												this.$emit('scroll', e)
							 | 
						|
											},
							 | 
						|
											handleScrolltolower (e) {
							 | 
						|
												if ( !this.loadmoreable || this.isLoadmore || this.loadmoreStatus == 'end' ) return
							 | 
						|
												this.isLoadmore = true
							 | 
						|
												this.loadmoreStatus = 'ready'
							 | 
						|
												this.$emit('loadmore', (state) => {
							 | 
						|
													this.loadmoreStatus = state
							 | 
						|
													this.isLoadmore = false
							 | 
						|
												})
							 | 
						|
											},
							 | 
						|
											handleScrolltoupper (e) {
							 | 
						|
												this.$emit('scrolltoupper', e)
							 | 
						|
											},
							 | 
						|
											pulldown () {
							 | 
						|
												if ( this.pulldownStatus == 'end' ) {
							 | 
						|
													this.stopRefresh()
							 | 
						|
													return
							 | 
						|
												}
							 | 
						|
												this.$emit('pulldown', (state) => {
							 | 
						|
													this.pulldownStatus = state
							 | 
						|
													this.stopRefresh()
							 | 
						|
												})
							 | 
						|
											},
							 | 
						|
											pullup () {
							 | 
						|
												if ( this.pullupStatus == 'end' ) {
							 | 
						|
													this.stopRefresh()
							 | 
						|
													return
							 | 
						|
												}
							 | 
						|
												this.$emit('pullup', (state) => {
							 | 
						|
													this.pullupStatus = state
							 | 
						|
													this.stopRefresh()
							 | 
						|
												})
							 | 
						|
											},
							 | 
						|
											startPulldown () {
							 | 
						|
												this.pulldownStatus = 'ready'
							 | 
						|
												this.refreshState = ''
							 | 
						|
												this.$nextTick(function () {
							 | 
						|
													this.refreshState = 'pulldown'
							 | 
						|
												})
							 | 
						|
											},
							 | 
						|
											startPullup () {
							 | 
						|
												this.pullupStatus = 'ready'
							 | 
						|
												this.refreshState = ''
							 | 
						|
												this.$nextTick(function () {
							 | 
						|
													this.refreshState = 'pullup'
							 | 
						|
												})
							 | 
						|
											},
							 | 
						|
											stopRefresh () {
							 | 
						|
												this.refreshState = ''
							 | 
						|
												this.$nextTick(function () {
							 | 
						|
													this.refreshState = 'stop'
							 | 
						|
												})
							 | 
						|
											},
							 | 
						|
											resetRefresh () {
							 | 
						|
												this.pulldownStatus = ''
							 | 
						|
												this.pullupStatus = ''
							 | 
						|
												this.refreshState = ''
							 | 
						|
												this.loadmoreState = ''
							 | 
						|
												this.isLoadmore = false
							 | 
						|
											},
							 | 
						|
											scrollToIndex (index, animated = false) {
							 | 
						|
												this.stopAutoplay()
							 | 
						|
												this.scrollIntoViewId = ''
							 | 
						|
												this.scrollWithAnimation = animated
							 | 
						|
												this.$nextTick(function () {
							 | 
						|
													this.scrollIntoViewId = 'yingbing-scroll-item_' + index
							 | 
						|
													this.$nextTick(function () {
							 | 
						|
														this.scrollWithAnimation = false
							 | 
						|
														setTimeout(() => {
							 | 
						|
															this.startAutoplay()
							 | 
						|
														}, 400)
							 | 
						|
													})
							 | 
						|
												})
							 | 
						|
											},
							 | 
						|
											getItemRect (index) {
							 | 
						|
												return new Promise(resolve => {
							 | 
						|
													uni.createSelectorQuery().in(this).select('#yingbing-scroll-item_' + index).boundingClientRect(data => {
							 | 
						|
														resolve(data)
							 | 
						|
													}).exec();
							 | 
						|
												})
							 | 
						|
											},
							 | 
						|
											pullingdown (threshold) {
							 | 
						|
												if ( this.pulldownStatus != 'end' ) {
							 | 
						|
													// #ifndef APP-NVUE
							 | 
						|
													if ( threshold >= readyHeight ) {
							 | 
						|
														this.pulldownStatus = 'ready'
							 | 
						|
													} else {
							 | 
						|
														this.pulldownStatus = 'pull'
							 | 
						|
													}
							 | 
						|
													// #endif
							 | 
						|
													// #ifdef APP-NVUE
							 | 
						|
													if ( threshold >= 195 ) {
							 | 
						|
														this.pulldownStatus = 'ready'
							 | 
						|
													} else {
							 | 
						|
														this.pulldownStatus = 'pull'
							 | 
						|
													}
							 | 
						|
													// #endif
							 | 
						|
												}
							 | 
						|
											},
							 | 
						|
											pullingup (threshold) {
							 | 
						|
												if ( this.pullupStatus != 'end' ) {
							 | 
						|
													// #ifndef APP-NVUE
							 | 
						|
													if ( threshold >= readyHeight ) {
							 | 
						|
														this.pullupStatus = 'ready'
							 | 
						|
													} else {
							 | 
						|
														this.pullupStatus = 'pull'
							 | 
						|
													}
							 | 
						|
													// #endif
							 | 
						|
													// #ifdef APP-NVUE
							 | 
						|
													if ( threshold >= 195 ) {
							 | 
						|
														this.pullupStatus = 'ready'
							 | 
						|
													} else {
							 | 
						|
														this.pullupStatus = 'pull'
							 | 
						|
													}
							 | 
						|
													// #endif
							 | 
						|
												}
							 | 
						|
											},
							 | 
						|
											setScrollTop (top) {
							 | 
						|
												this.scrollTop = top
							 | 
						|
												this.scrollTopRecord = top
							 | 
						|
											},
							 | 
						|
											startAutoplay () {
							 | 
						|
												this.stopAutoplay()
							 | 
						|
												this.scrollTop = this.scrollTopRecord
							 | 
						|
												if ( this.autoplay && this.data.length > 0 ) {
							 | 
						|
													this.autoplayTimer = setInterval(() => {
							 | 
						|
														if ( this.scrollTop - this.scrollTopRecord > 2 ) this.scrollTop = this.scrollTopRecord//如果scrollTop比滚动距离大2像素,说明发生过等待章节加载,需要重新赋值scrollTop真实的滚动距离
							 | 
						|
														this.scrollTop += 1
							 | 
						|
													}, 20)
							 | 
						|
												}
							 | 
						|
											},
							 | 
						|
											stopAutoplay () {
							 | 
						|
												if ( this.autoplayTimer ) {
							 | 
						|
													clearInterval(this.autoplayTimer)
							 | 
						|
													this.autoplayTimer = null
							 | 
						|
												}
							 | 
						|
											}
							 | 
						|
										},
							 | 
						|
										watch: {
							 | 
						|
											autoplay () {
							 | 
						|
												this.startAutoplay()
							 | 
						|
											}
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
								</script>
							 | 
						|
								<!-- #ifdef APP-VUE || H5 || MP-WEIXIN || MP-QQ -->
							 | 
						|
								<script module="pulldownwxs" lang="wxs" src="./pulldown.wxs"></script>
							 | 
						|
								<!-- #endif -->
							 | 
						|
								
							 | 
						|
								<style scoped>
							 | 
						|
									/* #ifdef APP-VUE || H5 */
							 | 
						|
									/deep/ .yingbing-scroll-view .uni-scroll-view::-webkit-scrollbar {
							 | 
						|
										display: none;
							 | 
						|
										width: 0 !important;
							 | 
						|
										height: 0 !important;
							 | 
						|
										-webkit-appearance: none;
							 | 
						|
										background: transparent;
							 | 
						|
									}
							 | 
						|
									/* #endif */
							 | 
						|
									/* #ifdef MP */
							 | 
						|
									/deep/ ::-webkit-scrollbar {
							 | 
						|
										display: none;
							 | 
						|
										width: 0 !important;
							 | 
						|
										height: 0 !important;
							 | 
						|
										-webkit-appearance: none;
							 | 
						|
										background: transparent;
							 | 
						|
									}
							 | 
						|
									/* #endif */
							 | 
						|
									.yingbing-scroller {
							 | 
						|
										/* #ifndef APP-NVUE */
							 | 
						|
										height: 100%;
							 | 
						|
										/* #endif */
							 | 
						|
										/* #ifdef APP-NVUE */
							 | 
						|
										flex: 1;
							 | 
						|
										/* #endif */
							 | 
						|
										position: relative;
							 | 
						|
										overflow: hidden;
							 | 
						|
									}
							 | 
						|
									.yingbing-scroller-wrapper {
							 | 
						|
										height: calc(100% + 160px);
							 | 
						|
										position: absolute;
							 | 
						|
										top: -80px;
							 | 
						|
										left: 0;
							 | 
						|
										right: 0;
							 | 
						|
										display: flex;
							 | 
						|
										flex-direction: column;
							 | 
						|
									}
							 | 
						|
									.yingbing-scroller-refresh {
							 | 
						|
										height: 80px;
							 | 
						|
										padding: 20px 0;
							 | 
						|
										box-sizing: border-box;
							 | 
						|
										display: flex;
							 | 
						|
										align-items: center;
							 | 
						|
										justify-content: center;
							 | 
						|
									}
							 | 
						|
									.yingbing-scroller-refresh-text {
							 | 
						|
										font-size: 13px;
							 | 
						|
										margin-left: 10px;
							 | 
						|
									}
							 | 
						|
									.yingbing-scroll {
							 | 
						|
										flex: 1;
							 | 
						|
										position: relative;
							 | 
						|
									}
							 | 
						|
									.yingbing-scroll-view {
							 | 
						|
										position: absolute;
							 | 
						|
										top: 0;
							 | 
						|
										left: 0;
							 | 
						|
										right: 0;
							 | 
						|
										bottom: 0;
							 | 
						|
									}
							 | 
						|
								</style>
							 |