<template>
							 | 
						|
									<view class="yingbing-whole-reader"
							 | 
						|
									id="yingbing-whole-reader"
							 | 
						|
									:data-start="start"
							 | 
						|
									:data-color="color"
							 | 
						|
									:data-title="title"
							 | 
						|
									:data-background="background"
							 | 
						|
									:data-split="split"
							 | 
						|
									:data-fontSize="fontSize"
							 | 
						|
									:data-fontFamily="fontFamily"
							 | 
						|
									:data-lineGap="lineGap"
							 | 
						|
									:data-topGap="topGap"
							 | 
						|
									:data-bottomGap="bottomGap"
							 | 
						|
									:data-slide="slide"
							 | 
						|
									:data-pageType="pageType"
							 | 
						|
									:data-backShow="backShow"
							 | 
						|
									:data-headerShow="headerShow"
							 | 
						|
									:data-footerShow="footerShow"
							 | 
						|
									:data-autoplay="autoplaySync"
							 | 
						|
									:data-interval="interval"
							 | 
						|
									:data-unableClickPage="unableClickPage"
							 | 
						|
									:data-selectable="selectable"
							 | 
						|
									:selectable="selectable" :change:selectable="wholeReader.selectableWatcher"
							 | 
						|
									:unableClickPage="unableClickPage" :change:unableClickPage="wholeReader.unableClickPageWatcher"
							 | 
						|
									:autoplay="autoplaySync" :change:autoplay="wholeReader.autoplayWatcher"
							 | 
						|
									:interval="interval" :change:interval="wholeReader.intervalWatcher"
							 | 
						|
									:content="contentSync" :change:content="wholeReader.contentWatcher"
							 | 
						|
									:fontSize="fontSize" :change:fontSize="wholeReader.fontSizeWatcher"
							 | 
						|
									:fontFamily="fontFamily" :change:fontFamily="wholeReader.fontFamilyWatcher"
							 | 
						|
									:split="split" :change:split="wholeReader.splitWatcher"
							 | 
						|
									:lineGap="lineGap" :change:lineGap="wholeReader.lineGapWatcher"
							 | 
						|
									:topGap="topGap" :change:topGap="wholeReader.topGapWatcher"
							 | 
						|
									:bottomGap="bottomGap" :change:bottomGap="wholeReader.bottomGapWatcher"
							 | 
						|
									:slide="slide" :change:slide="wholeReader.slideWatcher"
							 | 
						|
									:pageType="pageType" :change:pageType="wholeReader.pageTypeWatcher"
							 | 
						|
									:backShow="backShow" :change:backShow="wholeReader.backShowWatcher"
							 | 
						|
									:headerShow="headerShow" :change:headerShow="wholeReader.headerShowWatcher"
							 | 
						|
									:footerShow="footerShow" :change:footerShow="wholeReader.footerShowWatcher"
							 | 
						|
									:background="background" :change:background="wholeReader.backgroundWatcher"
							 | 
						|
									:color="color" :change:color="wholeReader.colorWatcher"
							 | 
						|
									:isRender="isRender" :change:isRender="wholeReader.renderWatcher"
							 | 
						|
									:isRefresh="isRefresh" :change:isRefresh="wholeReader.refreshWatcher"
							 | 
						|
									:pageTo="pageTo" :change:pageTo="wholeReader.pageToWatcher"
							 | 
						|
									@touchstart="touchstart" @touchmove="touchmove" @touchend="touchend">
							 | 
						|
									</view>
							 | 
						|
								</template>
							 | 
						|
								
							 | 
						|
								<script>
							 | 
						|
									import TouchClickMixin from '../mixin/touch-click.js'
							 | 
						|
									export default {
							 | 
						|
										options: {
							 | 
						|
											addGlobalClass: true,
							 | 
						|
											virtualHost: true,  //  将自定义节点设置成虚拟的,更加接近Vue组件的表现。我们不希望自定义组件的这个节点本身可以设置样式、响应 flex 布局等,而是希望自定义组件内部的第一层节点能够响应 flex 布局或者样式由自定义组件本身完全决定
							 | 
						|
										},
							 | 
						|
										mixins: [TouchClickMixin],
							 | 
						|
										props: {
							 | 
						|
											//自动播放
							 | 
						|
											autoplay: {
							 | 
						|
												type: Boolean,
							 | 
						|
												default: false
							 | 
						|
											},
							 | 
						|
											interval: {
							 | 
						|
												type: [Number, String],
							 | 
						|
												default: 5000
							 | 
						|
											},
							 | 
						|
											//字体颜色
							 | 
						|
											color: {
							 | 
						|
												type: String,
							 | 
						|
												default: '#333333'
							 | 
						|
											},
							 | 
						|
											//字体大小(单位px)
							 | 
						|
											fontSize: {
							 | 
						|
												type: [Number, String],
							 | 
						|
												default: 15
							 | 
						|
											},
							 | 
						|
											fontFamily: {
							 | 
						|
												type: String,
							 | 
						|
												default: 'Arial'
							 | 
						|
											},
							 | 
						|
											//背景颜色
							 | 
						|
											background: {
							 | 
						|
												type: String,
							 | 
						|
												default: '#fcd281'
							 | 
						|
											},
							 | 
						|
											//分隔符
							 | 
						|
											split: {
							 | 
						|
												type: String,
							 | 
						|
												default: ''
							 | 
						|
											},
							 | 
						|
											//翻页方式
							 | 
						|
											pageType: {
							 | 
						|
												type: String,
							 | 
						|
												default: 'scroll'
							 | 
						|
											},
							 | 
						|
											//行间距(单位px)
							 | 
						|
											lineGap: {
							 | 
						|
												type: [Number, String],
							 | 
						|
												default: 15
							 | 
						|
											},
							 | 
						|
											//页面左右边距(单位px)
							 | 
						|
											slide: {
							 | 
						|
												type: [Number, String],
							 | 
						|
												default: 20
							 | 
						|
											},
							 | 
						|
											//页面上边距(单位px)
							 | 
						|
											topGap: {
							 | 
						|
												type: [Number, String],
							 | 
						|
												default: 10
							 | 
						|
											},
							 | 
						|
											//页面下边距(单位px)
							 | 
						|
											bottomGap: {
							 | 
						|
												type: [Number, String],
							 | 
						|
												default: 10
							 | 
						|
											},
							 | 
						|
											backShow: {
							 | 
						|
												type: Boolean,
							 | 
						|
												default: false
							 | 
						|
											},
							 | 
						|
											headerShow: {
							 | 
						|
												type: Boolean,
							 | 
						|
												default: true
							 | 
						|
											},
							 | 
						|
											footerShow: {
							 | 
						|
												type: Boolean,
							 | 
						|
												default: true
							 | 
						|
											},
							 | 
						|
											//是否关闭点击左右2侧位置翻页
							 | 
						|
											unableClickPage: {
							 | 
						|
												type: Boolean,
							 | 
						|
												default: false
							 | 
						|
											},
							 | 
						|
											//开启文本选择
							 | 
						|
											selectable: {
							 | 
						|
												type: Boolean,
							 | 
						|
												default: false
							 | 
						|
											}
							 | 
						|
										},
							 | 
						|
										computed: {
							 | 
						|
											contentSync () {
							 | 
						|
												return {content: this.content}
							 | 
						|
											}
							 | 
						|
										},
							 | 
						|
										data () {
							 | 
						|
											return {
							 | 
						|
												title: '',
							 | 
						|
												content: '',
							 | 
						|
												start: 0,
							 | 
						|
												isRender: false,//是否渲染页面
							 | 
						|
												isRefresh: false,//是否刷新页面
							 | 
						|
												pageTo: 0
							 | 
						|
											}
							 | 
						|
										},
							 | 
						|
										created() {
							 | 
						|
											this.autoplaySync = this.autoplay
							 | 
						|
										},
							 | 
						|
										beforeDestroy() {
							 | 
						|
											if ( this.touchTimer ) {//清楚定时任务
							 | 
						|
												clearTimeout(this.touchTimer)
							 | 
						|
												this.touchTimer = null
							 | 
						|
											}
							 | 
						|
											if ( this.longTimer ) {//清楚定时任务
							 | 
						|
												clearTimeout(this.longTimer)
							 | 
						|
												this.longTimer = null
							 | 
						|
											}
							 | 
						|
										},
							 | 
						|
										methods: {
							 | 
						|
											//初始化
							 | 
						|
											init ({content, title, start}) {
							 | 
						|
												this.content = content
							 | 
						|
												this.title = title
							 | 
						|
												this.$emit('setCatalog', this.getCatalog(this.content));
							 | 
						|
												this.change(start)
							 | 
						|
											},
							 | 
						|
											//跳转
							 | 
						|
											async change (start) {
							 | 
						|
												const rect = await this.getRect()
							 | 
						|
												this.windowWidth = rect.width
							 | 
						|
												this.windowHeight = rect.height
							 | 
						|
												this.start = parseInt(start)
							 | 
						|
												this.isRender = false
							 | 
						|
												this.$nextTick(function () {
							 | 
						|
													this.isRender = true
							 | 
						|
												})
							 | 
						|
											},
							 | 
						|
											//刷新
							 | 
						|
											async refresh () {
							 | 
						|
												const rect = await this.getRect()
							 | 
						|
												this.windowWidth = rect.width
							 | 
						|
												this.windowHeight = rect.height
							 | 
						|
												this.isRefresh = false
							 | 
						|
												this.$nextTick(function () {
							 | 
						|
													this.isRefresh = true
							 | 
						|
												})
							 | 
						|
											},
							 | 
						|
											prev () {
							 | 
						|
												this.pageTo = 0
							 | 
						|
												this.$nextTick(function(){
							 | 
						|
													this.pageTo = -1
							 | 
						|
												})
							 | 
						|
											},
							 | 
						|
											next () {
							 | 
						|
												this.pageTo = 0
							 | 
						|
												this.$nextTick(function(){
							 | 
						|
													this.pageTo = 1
							 | 
						|
												})
							 | 
						|
											},
							 | 
						|
											//抛出阅读页面改变事件
							 | 
						|
											handleChange (e) {
							 | 
						|
												this.$emit('change', e)
							 | 
						|
											},
							 | 
						|
											//往后翻页完成事件
							 | 
						|
											handleEnded () {
							 | 
						|
												this.$emit('ended')
							 | 
						|
											},
							 | 
						|
											//往前翻页完成事件
							 | 
						|
											handleStarted () {
							 | 
						|
												this.$emit('started')
							 | 
						|
											},
							 | 
						|
											handleBack () {
							 | 
						|
												this.$emit('back')
							 | 
						|
											},
							 | 
						|
											//使用正则获取章节目录 并抛出事件
							 | 
						|
											getCatalog (content) {
							 | 
						|
												// const reg = new RegExp(/(第?[一二两三四五六七八九十○零百千万亿0-91234567890※✩★☆]{1,6}[章回卷节折篇幕集部]?[、.-\s][^\n]*)[_,-]?/g);
							 | 
						|
												const reg = new RegExp(/(第+[一二两三四五六七八九十○零百千万亿0-91234567890※✩★☆]{1,6}[章回卷节折篇幕集部]?[、.-\s::,,][^\n]*)[_,-]?/g)
							 | 
						|
												let match = '';
							 | 
						|
												let catalog = [];
							 | 
						|
												let chapter = 0
							 | 
						|
												while ((match = reg.exec(content)) != null) {
							 | 
						|
													chapter++
							 | 
						|
													catalog.push({
							 | 
						|
														title: match[0],
							 | 
						|
														start: match.index
							 | 
						|
													})
							 | 
						|
												}
							 | 
						|
												return catalog.length > 0 ? catalog : [{
							 | 
						|
													start: 0,
							 | 
						|
													title: this.title || '整章'
							 | 
						|
												}]
							 | 
						|
											},
							 | 
						|
											getRect () {
							 | 
						|
												return new Promise(resolve => {
							 | 
						|
													uni.createSelectorQuery().in(this).select('.yingbing-whole-reader').boundingClientRect(data => {
							 | 
						|
														resolve(data)
							 | 
						|
													}).exec();
							 | 
						|
												})
							 | 
						|
											}
							 | 
						|
										},
							 | 
						|
										watch: {
							 | 
						|
											autoplay (newVal) {
							 | 
						|
												this.autoplaySync = newVal
							 | 
						|
											}
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
								</script>
							 | 
						|
								<!-- #ifdef H5 || APP-VUE -->
							 | 
						|
								<script lang="renderjs" module="wholeReader" type="module">
							 | 
						|
									import Wholereader from "./wholereader.js"
							 | 
						|
									export default {
							 | 
						|
										data () {
							 | 
						|
											return {
							 | 
						|
												content: '',
							 | 
						|
												whole: null
							 | 
						|
											}
							 | 
						|
										},
							 | 
						|
										methods: {
							 | 
						|
											renderWatcher (newVal) {
							 | 
						|
												if ( newVal && this.content ) {
							 | 
						|
													if ( this.whole ) this.whole.destroy()
							 | 
						|
													this.whole = new Wholereader({
							 | 
						|
														container: document.querySelector('#yingbing-whole-reader'),
							 | 
						|
														autoplay: this.getData('autoplay') == 'true' ? true : false,
							 | 
						|
														interval: this.getData('interval'),
							 | 
						|
														content: this.getData('content'),
							 | 
						|
														title: this.getData('title'),
							 | 
						|
														color: this.getData('color'),
							 | 
						|
														background: this.getData('background'),
							 | 
						|
														fontSize: this.getData('fontSize'),
							 | 
						|
														fontFamily: this.getData('fontFamily'),
							 | 
						|
														slide: this.getData('slide'),
							 | 
						|
														topGap: this.getData('topGap'),
							 | 
						|
														bottomGap: this.getData('bottomGap'),
							 | 
						|
														lineGap: this.getData('lineGap'),
							 | 
						|
														split: this.getData('split'),
							 | 
						|
														headerShow: this.getData('headerShow') == 'true' ? true : false,
							 | 
						|
														footerShow: this.getData('footerShow') == 'true' ? true : false,
							 | 
						|
														backShow: this.getData('backShow') == 'true' ? true : false,
							 | 
						|
														pageType: this.getData('pageType'),
							 | 
						|
														unableClickPage: this.getData('unableClickPage') == 'true' ? true : false,
							 | 
						|
														selectable: this.getData('selectable') == 'true' ? true : false
							 | 
						|
													})
							 | 
						|
													this.whole.render(this.getData('start'))//开始渲染页面
							 | 
						|
													this.whole.on('change', e => {//注册翻页改变事件
							 | 
						|
														this.triggerMethod('handleChange', e)
							 | 
						|
													})
							 | 
						|
													this.whole.on('ended', () => {//注册往后翻页完成事件
							 | 
						|
														this.triggerMethod('handleEnded')
							 | 
						|
													})
							 | 
						|
													this.whole.on('started', () => {//注册往前翻页完成事件
							 | 
						|
														this.triggerMethod('handleStarted')
							 | 
						|
													})
							 | 
						|
													this.whole.on('back', () => {//点击返回按钮事件
							 | 
						|
														this.triggerMethod('handleBack')
							 | 
						|
													})
							 | 
						|
												}
							 | 
						|
											},
							 | 
						|
											refreshWatcher (newVal) {
							 | 
						|
												if ( this.refreshTimer ) {
							 | 
						|
													window.clearTimeout(this.refreshTimer)
							 | 
						|
													this.refreshTimer = null
							 | 
						|
												}
							 | 
						|
												if ( newVal && this.whole ) {
							 | 
						|
													this.refreshTimer = window.setTimeout(() => {
							 | 
						|
														 this.whole.refresh()
							 | 
						|
													}, 200)
							 | 
						|
												}
							 | 
						|
											},
							 | 
						|
											pageToWatcher (newVal) {
							 | 
						|
												if ( newVal == -1 ) this.whole && this.whole.prev()
							 | 
						|
												if ( newVal == 1 ) this.whole && this.whole.next()
							 | 
						|
											},
							 | 
						|
											autoplayWatcher (newVal) {
							 | 
						|
												this.whole && this.whole.setConfig('autoplay', newVal)
							 | 
						|
											},
							 | 
						|
											intervalWatcher (newVal) {
							 | 
						|
												this.whole && this.whole.setConfig('interval', newVal)
							 | 
						|
											},
							 | 
						|
											contentWatcher (newVal, oldVal) {
							 | 
						|
												this.content = newVal.content
							 | 
						|
											},
							 | 
						|
											fontSizeWatcher (newVal) {
							 | 
						|
												this.whole && this.whole.setConfig('fontSize', newVal)
							 | 
						|
												this.refreshWatcher(true)
							 | 
						|
											},
							 | 
						|
											fontFamilyWatcher (newVal) {
							 | 
						|
												this.whole && this.whole.setConfig('fontFamily', newVal)
							 | 
						|
												this.refreshWatcher(true)
							 | 
						|
											},
							 | 
						|
											splitWatcher (newVal) {
							 | 
						|
												this.whole && this.whole.setConfig('split', newVal)
							 | 
						|
												this.refreshWatcher(true)
							 | 
						|
											},
							 | 
						|
											lineGapWatcher (newVal) {
							 | 
						|
												this.whole && this.whole.setConfig('lineGap', newVal)
							 | 
						|
												this.refreshWatcher(true)
							 | 
						|
											},
							 | 
						|
											topGapWatcher (newVal) {
							 | 
						|
												this.whole && this.whole.setConfig('topGap', newVal)
							 | 
						|
												this.refreshWatcher(true)
							 | 
						|
											},
							 | 
						|
											bottomGapWatcher (newVal) {
							 | 
						|
												this.whole && this.whole.setConfig('bottomGap', newVal)
							 | 
						|
												this.refreshWatcher(true)
							 | 
						|
											},
							 | 
						|
											slideWatcher (newVal) {
							 | 
						|
												this.whole && this.whole.setConfig('slide', newVal)
							 | 
						|
												this.refreshWatcher(true)
							 | 
						|
											},
							 | 
						|
											pageTypeWatcher (newVal) {
							 | 
						|
												this.whole && this.whole.setConfig('pageType', newVal)
							 | 
						|
												this.refreshWatcher(true)
							 | 
						|
											},
							 | 
						|
											backShowWatcher (newVal) {
							 | 
						|
												this.whole && this.whole.setConfig('backShow', newVal)
							 | 
						|
												this.refreshWatcher(true)
							 | 
						|
											},
							 | 
						|
											headerShowWatcher (newVal) {
							 | 
						|
												this.whole && this.whole.setConfig('headerShow', newVal)
							 | 
						|
												this.refreshWatcher(true)
							 | 
						|
											},
							 | 
						|
											footerShowWatcher (newVal) {
							 | 
						|
												this.whole && this.whole.setConfig('footerShow', newVal)
							 | 
						|
												this.refreshWatcher(true)
							 | 
						|
											},
							 | 
						|
											backgroundWatcher (newVal) {
							 | 
						|
												this.whole && this.whole.setConfig('background', newVal)
							 | 
						|
												this.refreshWatcher(true)
							 | 
						|
											},
							 | 
						|
											colorWatcher (newVal) {
							 | 
						|
												this.whole && this.whole.setConfig('color', newVal)
							 | 
						|
												this.refreshWatcher(true)
							 | 
						|
											},
							 | 
						|
											selectableWatcher (newVal) {
							 | 
						|
												this.whole && this.whole.setConfig('selectable', newVal)
							 | 
						|
												this.refreshWatcher(true)
							 | 
						|
											},
							 | 
						|
											unableClickPageWatcher (newVal) {
							 | 
						|
												this.whole && this.whole.setConfig('unableClickPage', newVal)
							 | 
						|
											},
							 | 
						|
											getData (name) {
							 | 
						|
												const dom = document.getElementById('yingbing-whole-reader')
							 | 
						|
												if ( name == 'content' ) {
							 | 
						|
													return this.content.replace(/\t/g, ' ').replace(/ /g, ' ')
							 | 
						|
												} else if ( ['fontSize', 'lineGap', 'topGap', 'bottomGap', 'slide', 'start', 'interval'].includes(name) ) {
							 | 
						|
													return parseInt(dom.getAttribute('data-' + name))
							 | 
						|
												} else {
							 | 
						|
													return dom.getAttribute('data-' + name)
							 | 
						|
												}
							 | 
						|
											},
							 | 
						|
											triggerMethod (name, args) {
							 | 
						|
												// #ifndef H5
							 | 
						|
												// UniViewJSBridge.publishHandler('onWxsInvokeCallMethod', {
							 | 
						|
												//   cid: this._$id,
							 | 
						|
												//   method: name,
							 | 
						|
												//   args: args
							 | 
						|
												// })
							 | 
						|
												this.$ownerInstance.callMethod(name, args)
							 | 
						|
												// #endif
							 | 
						|
												// #ifdef H5
							 | 
						|
												this[name](args)
							 | 
						|
												// #endif
							 | 
						|
											}
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
								</script>
							 | 
						|
								<!-- #endif -->
							 | 
						|
								
							 | 
						|
								<style scoped>
							 | 
						|
									@import url(/uni_modules/yingbing-ReadPage/components/yingbing-whole-reader/wholereader.css);
							 | 
						|
									.yingbing-whole-reader {
							 | 
						|
										width: 100%;
							 | 
						|
										height: 100%;
							 | 
						|
										box-sizing: border-box;
							 | 
						|
										overflow: hidden;
							 | 
						|
									}
							 | 
						|
									.yingbing-reader-content-loading {
							 | 
						|
										display: flex;
							 | 
						|
										flex-direction: column;
							 | 
						|
										align-items: center;
							 | 
						|
										justify-content: center;
							 | 
						|
									}
							 | 
						|
									.yingbing-reader-content-loading-text {
							 | 
						|
										margin-top: 10px;
							 | 
						|
										font-size: 15px;
							 | 
						|
									}
							 | 
						|
									.yingbing-reader-content-loading-tip {
							 | 
						|
										margin-top: 10px;
							 | 
						|
										font-size: 12px;
							 | 
						|
									}
							 | 
						|
								</style>
							 |