|  | export default function Wholereader ({container, autoplay, interval, content, title, color, background, fontSize, fontFamily, split, lineGap, topGap, bottomGap, slide, pageType, backShow, headerShow, footerShow, unableClickPage, selectable }){ | 
						
						
							|  | 	if(!(this instanceof Wholereader)){ //如果this不是指向MyClass | 
						
						
							|  | 	    throw new TypeError("TypeError: Class constructor Wholereader cannot be invoked without 'new'") | 
						
						
							|  | 	} | 
						
						
							|  |    this.container = typeof container == 'string' ? document.querySelector('#' + container) : container//容器 | 
						
						
							|  |    this.content = content || ''//小说类容 | 
						
						
							|  |    this.title = title || ''//小说标题 | 
						
						
							|  |    this.color = color || '#333333'//字体颜色 | 
						
						
							|  |    this.background = background || '#fcd281'//页面背景 | 
						
						
							|  |    this.fontSize = parseInt(fontSize || 15)//字体大小 | 
						
						
							|  |    this.fontFamily = fontFamily || 'Microsoft YaHei, 微软雅黑'//字体 | 
						
						
							|  |    this.split = split || ''//分隔符 | 
						
						
							|  |    this.lineGap = parseInt(lineGap || 15)//行间隔 | 
						
						
							|  |    this.topGap = parseInt(topGap || 10)//顶部间隔 | 
						
						
							|  |    this.bottomGap = parseInt(bottomGap || 10)//底部间隔 | 
						
						
							|  |    this.slide = parseInt(slide || 20)//左右间隔 | 
						
						
							|  |    this.pageType = pageType || 'real'//翻页类型 | 
						
						
							|  |    this.backShow = backShow//显示返回按钮 | 
						
						
							|  |    this.headerShow = headerShow//显示顶部 | 
						
						
							|  |    this.footerShow = footerShow//显示底部 | 
						
						
							|  |    this.unableClickPage = unableClickPage//关闭点击翻页 | 
						
						
							|  |    this.selectable = selectable//开启文本选择 | 
						
						
							|  |    this.autoplay = autoplay || false//自动播放 | 
						
						
							|  |    this.interval = interval || 5000//自动播放周期 | 
						
						
							|  |    this._contents = []//内容集合 | 
						
						
							|  |    this._wrapperEl = null//内容盒子 | 
						
						
							|  |    this._scrollerEl = null//滚动盒子 | 
						
						
							|  |    this._viewWidth = 0//容器宽度 | 
						
						
							|  |    this._viewHeight = 0//容器高度 | 
						
						
							|  |    this._contentWidth = 0//内容宽度 | 
						
						
							|  |    this._contentHeight = 0//内容高度 | 
						
						
							|  |    this._start = 0//当前页开始位置 | 
						
						
							|  |    this._end = 0//当前页开始位置 | 
						
						
							|  |    this._pageWating = false//翻页等待 | 
						
						
							|  |    this._touchTimer = null//触摸事件定时器 | 
						
						
							|  |    this._autoplayTimer = null//自动播放定时器 | 
						
						
							|  |    this._touchTime = 0//触摸时间 | 
						
						
							|  |    this._touchstartX = 0//触摸开始点 | 
						
						
							|  |    this._moveX = 0//移动位置 | 
						
						
							|  |    this._pageEl = null //翻页对象 | 
						
						
							|  |    this._pageDirection = ''//翻页方向 | 
						
						
							|  |    this._updownloading = false//上下章节加载等待 | 
						
						
							|  |    this._eventCallback = {}//事件 | 
						
						
							|  | } | 
						
						
							|  | //渲染页面 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'render',{ | 
						
						
							|  |     value: async function(start){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader.render is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  |         if ( this.container && typeof this.container != 'undefined' ) { | 
						
						
							|  | 			this._stopAutoplay() | 
						
						
							|  | 			this._contents = this._contentToArr()//将文本转为数组 | 
						
						
							|  | 			if ( this._wrapperEl ) this.container.removeChild(this._wrapperEl)//清空容器 | 
						
						
							|  | 			this._viewWidth = this.container.offsetWidth//获取容器宽度 | 
						
						
							|  | 			this._viewHeight = this.container.offsetHeight//获取容器高度 | 
						
						
							|  | 			this._contentWidth = this._viewWidth - (2 * this.slide)//获取内容宽度 | 
						
						
							|  | 			this._contentHeight = this._viewHeight - this.topGap - this.bottomGap - (this.headerShow ? 30 : 0) - (this.footerShow ? 30 : 0)//获取内容高度 | 
						
						
							|  | 			//创建内容盒子 | 
						
						
							|  | 			this._wrapperEl = document.createElement('DIV') | 
						
						
							|  | 			this._wrapperEl.setAttribute('class', ( this.selectable ? 'whole-reader-wrapper-selectable ' : '' ) + 'whole-reader-wrapper ' + (this.pageType == 'scroll' ? 'whole-scroll-reader' : 'whole-flip-reader')) | 
						
						
							|  | 			this.container.appendChild(this._wrapperEl) | 
						
						
							|  | 			this._start = start//记录当前页开始位置 | 
						
						
							|  | 			const pages = []; | 
						
						
							|  | 			if ( start > 0 ) pages.push(this._computedPrevText(start))//计算上一页 | 
						
						
							|  | 			pages.push(this._computedNextText(start))//计算当前页 | 
						
						
							|  | 			this._end = pages[pages.length - 1].end | 
						
						
							|  | 			if ( pages[pages.length - 1].end < this._contents.length - 1 ) pages.push(this._computedNextText(pages[pages.length - 1].end))//计算下一页 | 
						
						
							|  | 			if ( this.pageType == 'scroll' ) {//滚动阅读 | 
						
						
							|  | 				this._wrapperEl.style.padding = `${this.topGap}px ${this.slide}px ${this.topGap}px ${this.slide}px`; | 
						
						
							|  | 				this._wrapperEl.style.background = this.background; | 
						
						
							|  | 				this._wrapperEl.style.color = this.color; | 
						
						
							|  | 				if ( this.headerShow ) {//开启头部显示 | 
						
						
							|  | 					const header = this._createHeaderDom() | 
						
						
							|  | 					this._wrapperEl.appendChild(header) | 
						
						
							|  | 				} | 
						
						
							|  | 				//创建滚动元素 | 
						
						
							|  | 				this._scrollerEl = document.createElement('div') | 
						
						
							|  | 				this._scrollerEl.setAttribute('class', 'whole-scroll-reader-content') | 
						
						
							|  | 				this._wrapperEl.appendChild(this._scrollerEl) | 
						
						
							|  | 				if ( this.footerShow ) {//开启底部显示 | 
						
						
							|  | 					const footer = await this._createFooterDom(this._start) | 
						
						
							|  | 					this._wrapperEl.appendChild(footer) | 
						
						
							|  | 				} | 
						
						
							|  | 				pages.forEach(page => { | 
						
						
							|  | 					this._scrollerEl.appendChild(this._createTextDom(page))//创建页面元素 | 
						
						
							|  | 				}) | 
						
						
							|  | 				const scrollItems = this._scrollerEl.getElementsByClassName('whole-scroll-reader-content-text') | 
						
						
							|  | 				let offsetHeight = 0; | 
						
						
							|  | 				for ( let i = 0; i < scrollItems.length; i++ ) { | 
						
						
							|  | 					offsetHeight += i > 0 ? scrollItems[i - 1].offsetHeight : 0; | 
						
						
							|  | 					if ( this._start >= scrollItems[i].getAttribute('start') && this._start < scrollItems[i].getAttribute('end') ) { | 
						
						
							|  | 						this._scrollerEl.scrollTop = offsetHeight; | 
						
						
							|  | 						this._end = scrollItems[i].getAttribute('end'); | 
						
						
							|  | 					} | 
						
						
							|  | 				} | 
						
						
							|  | 				this._scrollerEl.onscroll = this._scroll.bind(this) | 
						
						
							|  | 			} else {//翻页阅读 | 
						
						
							|  | 				for ( let i = 0; i < pages.length; i++ ) this._wrapperEl.appendChild(await this._createPageDom(pages[i]))//创建页面元素 | 
						
						
							|  | 				this._pageChange()//触发change | 
						
						
							|  | 				//绑定touch事件 | 
						
						
							|  | 				this._wrapperEl.ontouchstart = this._touchstart.bind(this) | 
						
						
							|  | 				this._wrapperEl.ontouchmove = this._touchmove.bind(this) | 
						
						
							|  | 				this._wrapperEl.ontouchend = this._touchaction.bind(this) | 
						
						
							|  | 				this._wrapperEl.ontouchcancel = this._touchaction.bind(this) | 
						
						
							|  | 				//兼容pc端 | 
						
						
							|  | 				this._wrapperEl.onmousedown = (e) => { | 
						
						
							|  | 					this._mousedown = true | 
						
						
							|  | 					this._touchstart({touches: [{pageX: e.pageX, pageY: e.pageY}]}) | 
						
						
							|  | 				} | 
						
						
							|  | 				this._wrapperEl.onmousemove = (e) => { | 
						
						
							|  | 					if ( !this._mousedown ) return | 
						
						
							|  | 					this._touchmove({touches: [{pageX: e.pageX, pageY: e.pageY}]}) | 
						
						
							|  | 				} | 
						
						
							|  | 				this._wrapperEl.onmouseup = (e) => { | 
						
						
							|  | 					this._mousedown = false | 
						
						
							|  | 					this._touchaction({touches: [{pageX: e.pageX, pageY: e.pageY}]}) | 
						
						
							|  | 				} | 
						
						
							|  | 			} | 
						
						
							|  | 			this._startAutoplay() | 
						
						
							|  |         } | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //刷新页面 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'refresh',{ | 
						
						
							|  |     value:function(){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader.refresh is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  |         if ( this.container && typeof this.container != 'undefined' ) { | 
						
						
							|  | 			if ( this.pageType != 'scroll' && this._wrapperEl && this._scrollerEl ) {//滚动阅读改为翻页阅读时 | 
						
						
							|  | 				this._wrapperEl.removeChild(this._scrollerEl) | 
						
						
							|  | 				this._scrollerEl = null | 
						
						
							|  | 			} | 
						
						
							|  | 			this.render(this._start) | 
						
						
							|  |         } | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //设置参数 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'setConfig',{ | 
						
						
							|  |     value:function(attribute, value){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader.setConfig is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  |         this[attribute] = value | 
						
						
							|  | 		if ( attribute == 'autoplay' ) this._startAutoplay() | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //销毁 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'destroy',{ | 
						
						
							|  |     value:function(){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader.destroy is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  | 		if ( this._wrapperEl ) { | 
						
						
							|  | 			this._stopAutoplay() | 
						
						
							|  | 			if ( this._touchtimer ) { | 
						
						
							|  | 				window.clearTimeout(this._touchtimer) | 
						
						
							|  | 				this._touchtimer = null | 
						
						
							|  | 			} | 
						
						
							|  | 			if ( this._scrollerEl ) { | 
						
						
							|  | 				this._wrapperEl.removeChild(this._scrollerEl) | 
						
						
							|  | 				this._scrollerEl = null | 
						
						
							|  | 			} | 
						
						
							|  | 			this.container.removeChild(this._wrapperEl) | 
						
						
							|  | 			this._wrapperEl = null | 
						
						
							|  | 			this._pageEl = null | 
						
						
							|  | 			this._eventCallback = {} | 
						
						
							|  | 		} | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | // 注册事件 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'on',{ | 
						
						
							|  |     value:function(name, callback){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader.on is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  | 		this._eventCallback[name] = callback | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //往前翻页 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'prev',{ | 
						
						
							|  |     value:function(){ | 
						
						
							|  | 		if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |           throw new TypeError("TypeError: Wholereader.prev is not a constructor") | 
						
						
							|  | 		} | 
						
						
							|  | 		if ( this.pageType == 'scroll' ) {//滚动阅读 | 
						
						
							|  | 			const items = this._scrollerEl.getElementsByClassName('whole-scroll-reader-content-text') | 
						
						
							|  | 			let index = 0 | 
						
						
							|  | 			for ( let i = 0; i < items.length; i++ ) if ( items[i].getAttribute('start') == this._start ) index = i | 
						
						
							|  | 			if ( index > 0 ) items[index - 1].scrollIntoView({behavior: 'smooth', 'block': 'end'})//滚动到上一个内容 | 
						
						
							|  | 			else this._scrollerEl.scrollTop = 0 | 
						
						
							|  | 		} else {//翻页阅读 | 
						
						
							|  | 			if ( !this._pageWating ) { | 
						
						
							|  | 				this._touchstartX = 1 | 
						
						
							|  | 				this._pageEl = this._getPageActived(-1) | 
						
						
							|  | 				this._pageDirection = 'prev' | 
						
						
							|  | 				this._touchaction() | 
						
						
							|  | 			} | 
						
						
							|  | 		} | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //往后翻页 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'next',{ | 
						
						
							|  |     value:function(){ | 
						
						
							|  | 		if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |           throw new TypeError("TypeError: Wholereader.next is not a constructor") | 
						
						
							|  | 		} | 
						
						
							|  | 		if ( this.pageType == 'scroll' ) {//滚动阅读 | 
						
						
							|  | 			const items = this._scrollerEl.getElementsByClassName('whole-scroll-reader-content-text') | 
						
						
							|  | 			let index = items.length - 1 | 
						
						
							|  | 			for ( let i = 0; i < items.length; i++ ) if ( items[i].getAttribute('start') == this._start ) index = i | 
						
						
							|  | 			if ( index < items.length - 1 ) items[index + 1].scrollIntoView({behavior: 'smooth'})//滚动到下一个内容 | 
						
						
							|  | 			else this._scrollerEl.scrollTop = this._scrollerEl.scrollHeight | 
						
						
							|  | 		} else {//翻页阅读 | 
						
						
							|  | 			if ( !this._pageWating ) { | 
						
						
							|  | 				this._touchstartX = this._viewWidth | 
						
						
							|  | 				this._pageEl = this._getPageActived(0) | 
						
						
							|  | 				this._pageDirection = 'next' | 
						
						
							|  | 				this._touchaction() | 
						
						
							|  | 			} | 
						
						
							|  | 		} | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //开启自动播放 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'_startAutoplay',{ | 
						
						
							|  |     value:function(){ | 
						
						
							|  | 		if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |           throw new TypeError("TypeError: Wholereader._startAutoplay is not a constructor") | 
						
						
							|  | 		} | 
						
						
							|  | 		this._stopAutoplay() | 
						
						
							|  | 		if ( !this.autoplay ) return | 
						
						
							|  | 		if ( this.pageType == 'scroll' ) {//滚动阅读 | 
						
						
							|  | 			this._autoplayTimer = window.setInterval(() => { | 
						
						
							|  | 				if ( this._scrollerEl.scrollTop < this._scrollerEl.scrollHeight - this._contentHeight ) this._scrollerEl.scrollTop += 1 | 
						
						
							|  | 			}, 20) | 
						
						
							|  | 		} else {//翻页阅读 | 
						
						
							|  | 			this._autoplayTimer = window.setTimeout(() => { | 
						
						
							|  | 				let index = 0 | 
						
						
							|  | 				const items = this._wrapperEl.getElementsByClassName('whole-flip-reader-page-item') | 
						
						
							|  | 				for ( let i = 0; i < items.length; i++ ) if ( items[i].getAttribute('start') == this._start ) index = i | 
						
						
							|  | 				if ( index < items.length - 1 ) this.next() | 
						
						
							|  | 				else this._startAutoplay() | 
						
						
							|  | 			}, this.interval) | 
						
						
							|  | 		} | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //关闭自动播放 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'_stopAutoplay',{ | 
						
						
							|  |     value:function(){ | 
						
						
							|  | 		if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |           throw new TypeError("TypeError: Wholereader._stopAutoplay is not a constructor") | 
						
						
							|  | 		} | 
						
						
							|  | 		if ( !this._autoplayTimer ) return | 
						
						
							|  | 		if ( this.pageType == 'scroll' ) window.clearInterval(this._autoplayTimer)//滚动阅读 | 
						
						
							|  | 		else window.clearTimeout(this._autoplayTimer)//翻页阅读 | 
						
						
							|  | 		this._autoplayTimer = null | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //创建一个独立的canvas画板,用于计算文字布局 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'_createComputedCanvas',{ | 
						
						
							|  |     value:function(){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader._createComputedCanvas is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  | 		const canvasDom = document.createElement('canvas'); | 
						
						
							|  | 		canvasDom.width = this._contentWidth; | 
						
						
							|  | 		canvasDom.height = this._contentHeight; | 
						
						
							|  | 		const context = canvasDom.getContext('2d', {alpha: false}); | 
						
						
							|  | 		context.font = this.fontSize + 'px ' + this.fontFamily | 
						
						
							|  | 		context.imageSmoothingEnabled = false | 
						
						
							|  | 		context.lineWidth = 1 | 
						
						
							|  | 		return context | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //测量文字(备用) | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'_measureText',{ | 
						
						
							|  |     value:function(text){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader._measureText is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  | 		const span = document.createElement('SPAN'); | 
						
						
							|  | 		span.style.fontSize = this.fontSize + 'px' | 
						
						
							|  | 		span.style.fontFamily = this.fontFamily | 
						
						
							|  | 		span.style.whiteSpace = 'pre-wrap' | 
						
						
							|  | 		span.innerHTML = text | 
						
						
							|  | 		document.body.appendChild(span) | 
						
						
							|  | 		const width = span.offsetWidth | 
						
						
							|  | 		document.body.removeChild(span) | 
						
						
							|  | 		return width | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //计算当前页和下一页的文字排版 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'_computedNextText',{ | 
						
						
							|  |     value:function(start, end){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader._computedNextText is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  | 		const context = this._createComputedCanvas() | 
						
						
							|  | 		let pageHeight = this.fontSize + this.lineGap, text = [], length = 0, lastIndex = 0 | 
						
						
							|  | 		const contentSync = end ? this._contents.slice(start, end) : this._contents.slice(start) | 
						
						
							|  | 		while ( pageHeight <= this._contentHeight ) { | 
						
						
							|  | 			text.push(''); | 
						
						
							|  | 			let lineWidth = 0 | 
						
						
							|  | 			for ( let i = lastIndex; i < contentSync.length; i++ ) { | 
						
						
							|  | 				const char = contentSync[i] | 
						
						
							|  | 				lineWidth += context.measureText(char).width; | 
						
						
							|  | 				// lineWidth += this._measureText(char) | 
						
						
							|  | 				if ( JSON.stringify(char) == JSON.stringify('\r') || JSON.stringify(char) == JSON.stringify('\n') ) { | 
						
						
							|  | 					length += 1 | 
						
						
							|  | 					end = start + length; | 
						
						
							|  | 					lastIndex = i + 1; | 
						
						
							|  | 					break; | 
						
						
							|  | 				} else if ( lineWidth >= this._contentWidth ) { | 
						
						
							|  | 					lastIndex = i; | 
						
						
							|  | 					break; | 
						
						
							|  | 				} else { | 
						
						
							|  | 					text[text.length - 1] += char | 
						
						
							|  | 					length += 1; | 
						
						
							|  | 					end = start + length; | 
						
						
							|  | 				} | 
						
						
							|  | 			} | 
						
						
							|  | 			pageHeight += this.fontSize + this.lineGap | 
						
						
							|  | 			if ( end >= contentSync.length - 1 + start ) break; | 
						
						
							|  | 		} | 
						
						
							|  | 		return {start, end, text}; | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //计算上一页的文字排版 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'_computedPrevText',{ | 
						
						
							|  |     value:function(end){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader._computedPrevText is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  |         const context = this._createComputedCanvas() | 
						
						
							|  |         let pageHeight = this.fontSize + this.lineGap, text = [], start = 0, length = 0, lastIndex1 = 0, lastIndex2 = 0 | 
						
						
							|  |         while ( pageHeight <= this._contentHeight ) { | 
						
						
							|  |         	if ( end - length > 0 ) { | 
						
						
							|  |         		text.unshift(''); | 
						
						
							|  |         		let lineWidth = 0, contentSync = this._contents.slice(0, end) | 
						
						
							|  |         		for ( let i = end - length - 1; i >= 0; i-- ) { | 
						
						
							|  | 					const char = contentSync[i] | 
						
						
							|  |         			lineWidth += context.measureText(char).width; | 
						
						
							|  | 					// lineWidth += this._measureText(char) | 
						
						
							|  |         			if ( JSON.stringify(char) == JSON.stringify('\r') || JSON.stringify(char) == JSON.stringify('\n') ) { | 
						
						
							|  |         				lastIndex1 = i - 1; | 
						
						
							|  |         				length += 1 | 
						
						
							|  |         				break; | 
						
						
							|  |         			} else if ( lineWidth >= this._contentWidth ) { | 
						
						
							|  |         				lastIndex1 = i; | 
						
						
							|  |         				break; | 
						
						
							|  |         			} else { | 
						
						
							|  |         				text[0] = char + text[0]; | 
						
						
							|  |         				length += 1 | 
						
						
							|  |         				start = end - length; | 
						
						
							|  |         			} | 
						
						
							|  | 					if ( start == 0 ) break; | 
						
						
							|  |         		} | 
						
						
							|  |         		pageHeight += this.fontSize + this.lineGap | 
						
						
							|  |         	} else { | 
						
						
							|  |         		if ( this.pageType != 'scroll' ) { | 
						
						
							|  |         			text.push(''); | 
						
						
							|  |         			let lineWidth = 0, contentSync = this._contents.slice(end) | 
						
						
							|  |         			for ( let i = lastIndex2; i < contentSync.length; i++ ) { | 
						
						
							|  | 						const char = contentSync[i] | 
						
						
							|  |         				lineWidth += context.measureText(char).width; | 
						
						
							|  | 						// lineWidth += this._measureText(char) | 
						
						
							|  |         				if ( JSON.stringify(char) == JSON.stringify('\r') || JSON.stringify(char) == JSON.stringify('\n') ) { | 
						
						
							|  |         					lastIndex2 = i + 1; | 
						
						
							|  |         					length += 1 | 
						
						
							|  |         					break; | 
						
						
							|  |         				} else if ( lineWidth >= this._contentWidth ) { | 
						
						
							|  |         					lastIndex2 = i; | 
						
						
							|  |         					break; | 
						
						
							|  |         				} else { | 
						
						
							|  |         					text[text.length - 1] += char; | 
						
						
							|  |         					length += 1; | 
						
						
							|  |         					end = start + length; | 
						
						
							|  |         				} | 
						
						
							|  |         			} | 
						
						
							|  |         			pageHeight += this.fontSize + this.lineGap | 
						
						
							|  |         			if ( end >= this._contents.length - 1 ) break; | 
						
						
							|  |         		} else break; | 
						
						
							|  |         	} | 
						
						
							|  |         } | 
						
						
							|  |         return {start, end, text} | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //创建页面元素 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'_createPageDom',{ | 
						
						
							|  |     value:async function(page){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader._createComputedCanvas is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  | 		//创建页面盒子 | 
						
						
							|  | 		const item = document.createElement('DIV'); | 
						
						
							|  | 		item.style.zIndex = this._contents.length - page.start; | 
						
						
							|  | 		item.setAttribute('class', 'whole-flip-reader-page-item whole-flip-reader-page-item-start_' + page.start + (this._start == page.start ? ' whole-flip-reader-page-item-actived' : '')); | 
						
						
							|  | 		item.setAttribute('start', page.start); | 
						
						
							|  | 		item.setAttribute('end', page.end); | 
						
						
							|  | 		//创建页面内容 | 
						
						
							|  | 		const content = document.createElement('div'); | 
						
						
							|  | 		content.setAttribute('class', 'whole-flip-reader-page-item-content') | 
						
						
							|  | 		content.style.width = this._viewWidth + 'px'; | 
						
						
							|  | 		content.style.height = this._viewHeight + 'px'; | 
						
						
							|  | 		content.style.background = this.background | 
						
						
							|  | 		content.style.color = this.color | 
						
						
							|  | 		content.style.padding = `${this.topGap}px ${this.slide}px ${this.topGap}px ${this.slide}px`; | 
						
						
							|  | 		if ( this.headerShow ) {//开启头部显示 | 
						
						
							|  | 			const header = this._createHeaderDom(); | 
						
						
							|  | 			content.appendChild(header); | 
						
						
							|  | 		} | 
						
						
							|  | 		//创建文字元素 | 
						
						
							|  | 		const text = this._createTextDom(page); | 
						
						
							|  | 		content.appendChild(text) | 
						
						
							|  | 		if ( this.footerShow ) {//开启底部显示 | 
						
						
							|  | 			const footer = await this._createFooterDom(page.start) | 
						
						
							|  | 			content.appendChild(footer) | 
						
						
							|  | 		} | 
						
						
							|  | 		item.appendChild(content); | 
						
						
							|  | 		//创建背景 | 
						
						
							|  | 		const bg = document.createElement('DIV'); | 
						
						
							|  | 		bg.setAttribute('class', 'whole-flip-reader-page-item-bg') | 
						
						
							|  | 		bg.style.height = Math.sqrt(Math.pow(this._viewHeight, 2) + Math.pow(this._viewWidth, 2)) + 'px'; | 
						
						
							|  | 		bg.style.background = this.background; | 
						
						
							|  | 		item.appendChild(bg); | 
						
						
							|  | 		//创建阴影区域 | 
						
						
							|  | 		const shadow = document.createElement('DIV'); | 
						
						
							|  | 		shadow.setAttribute('class', 'whole-flip-reader-page-item-shadow') | 
						
						
							|  | 		item.appendChild(shadow); | 
						
						
							|  | 		if ( page.start < this._start ) this._pageAnimation(-this._viewWidth, 0, { box: item, content, bg, shadow })//如果是上一页内容则设置已经翻页样式 | 
						
						
							|  | 		return item | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //创建头部元素 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'_createHeaderDom',{ | 
						
						
							|  |     value:function(){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader._createHeaderDom is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  | 		const header = document.createElement('DIV'); | 
						
						
							|  | 		header.setAttribute('class', 'whole-reader-header') | 
						
						
							|  | 		header.innerHTML = `<span class="whole-reader-header-text" style="color: ${this.color}">${this.title}</span>` | 
						
						
							|  | 		if ( this.backShow ) { | 
						
						
							|  | 			const back = document.createElement('DIV') | 
						
						
							|  | 			back.setAttribute('class', 'whole-reader-header-back') | 
						
						
							|  | 			back.style.borderTopColor = this.color | 
						
						
							|  | 			back.style.borderLeftColor = this.color | 
						
						
							|  | 			back.ontouchstart = function (e) { e.stopPropagation && e.stopPropagation(); } | 
						
						
							|  | 			back.ontouchmove = function (e) { e.stopPropagation && e.stopPropagation(); } | 
						
						
							|  | 			back.onmousedown = function (e) { e.stopPropagation && e.stopPropagation(); } | 
						
						
							|  | 			back.onmousemove = function (e) { e.stopPropagation && e.stopPropagation(); } | 
						
						
							|  | 			back.ontouchend = (e) => { | 
						
						
							|  | 				e.stopPropagation && e.stopPropagation(); | 
						
						
							|  | 				window.setTimeout(() => { this._eventCallback.back && this._eventCallback.back() }, 50)//不加延迟可能会造成返回或者跳转页面时,触发页面相同位置点击事件 | 
						
						
							|  | 			} | 
						
						
							|  | 			back.onmouseup = (e) => { | 
						
						
							|  | 				e.stopPropagation && e.stopPropagation(); | 
						
						
							|  | 				if ( !this._mousedown ) return | 
						
						
							|  | 				window.setTimeout(() => { this._eventCallback.back && this._eventCallback.back() }, 50)//不加延迟可能会造成返回或者跳转页面时,触发页面相同位置点击事件 | 
						
						
							|  | 			} | 
						
						
							|  | 			header.insertBefore(back, header.firstChild) | 
						
						
							|  | 		} | 
						
						
							|  | 		// if ( this.backShow ) header.innerHTML = `<div class="whole-reader-header-back" style="border-top-color: ${this.color};border-left-color: ${this.color}"></div>` + header.innerHTML | 
						
						
							|  | 		return header | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //创建底部元素 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'_createFooterDom',{ | 
						
						
							|  |     value:async function(start){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader._createFooterDom is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  | 		const progress = ((start / this._contents.length) * 100).toFixed(2) | 
						
						
							|  | 		const d = new Date() | 
						
						
							|  | 		const time = (d.getHours() < 10 ? ('0' + d.getHours()) : d.getHours()) + ':' + (d.getMinutes() < 10 ? ('0' + d.getMinutes()) : d.getMinutes()) | 
						
						
							|  | 		const footer = document.createElement('DIV'); | 
						
						
							|  | 		footer.setAttribute('class', 'whole-reader-footer') | 
						
						
							|  | 		footer.innerHTML = ` | 
						
						
							|  | 		<div class="whole-reader-footer-left"> | 
						
						
							|  | 			${await this._createBatteryDom()} | 
						
						
							|  | 			<span class="whole-reader-footer-text" style="color: ${this.color}">${time}</span> | 
						
						
							|  | 		</div> | 
						
						
							|  | 		<span class="whole-reader-footer-text">${progress}%</span> | 
						
						
							|  | 		` | 
						
						
							|  | 		return footer | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //创建电池元素 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'_createBatteryDom',{ | 
						
						
							|  |     value: async function(){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader._createBatteryDom is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  | 		const max = 16 | 
						
						
							|  | 		const res = window.navigator.getBattery ? await window.navigator.getBattery() : {level: 1} | 
						
						
							|  | 		const value = res.level * max | 
						
						
							|  | 		return ` | 
						
						
							|  | 			<div class="whole-reader-battery"> | 
						
						
							|  | 				<div class="whole-reader-battery-wrapper" :style="border-color: ${this.color}"> | 
						
						
							|  | 					<div class="whole-reader-battery-content"> | 
						
						
							|  | 						<div class="whole-reader-battery-content-value" style="background-color: ${this.color};width: ${value}px"></div> | 
						
						
							|  | 					</div> | 
						
						
							|  | 				</div> | 
						
						
							|  | 				<div class="whole-reader-battery-top" style="background-color: ${this.color}"></div> | 
						
						
							|  | 			</div> | 
						
						
							|  | 		` | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //创建文字元素 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'_createTextDom',{ | 
						
						
							|  |     value:function(page){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader._createTextDom is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  | 		const dom = document.createElement('DIV') | 
						
						
							|  | 		dom.setAttribute('class', this.pageType == 'scroll' ? 'whole-scroll-reader-content-text' : 'whole-flip-reader-content-text') | 
						
						
							|  | 		dom.setAttribute('start', page.start) | 
						
						
							|  | 		dom.setAttribute('end', page.end) | 
						
						
							|  | 		page.text.forEach(t => { | 
						
						
							|  | 			const p = document.createElement('P'); | 
						
						
							|  | 			p.style.height = this.fontSize + 'px'; | 
						
						
							|  | 			p.style.marginTop = this.lineGap + 'px'; | 
						
						
							|  | 			p.style.fontSize = this.fontSize + 'px'; | 
						
						
							|  | 			p.style.fontFamily = this.fontFamily; | 
						
						
							|  | 			p.style.whiteSpace = 'pre-wrap'; | 
						
						
							|  | 			p.innerHTML = t || ' '; | 
						
						
							|  | 			dom.appendChild(p) | 
						
						
							|  | 		}) | 
						
						
							|  | 		return dom | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //滚动模式滚动事件 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'_scroll',{ | 
						
						
							|  |     value: async function(e){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader._scroll is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  | 		try{ | 
						
						
							|  | 			const scrollItems = this._scrollerEl.getElementsByClassName('whole-scroll-reader-content-text'); | 
						
						
							|  | 			const scrollTop = this._scrollerEl.scrollTop + this.topGap + this.bottomGap + (this.headerShow ? 30 : 0) + (this.footerShow ? 30 : 0) | 
						
						
							|  | 			for ( let i = 0; i < scrollItems.length; i++ ) { | 
						
						
							|  | 				const offsetTop1 = scrollItems[i].offsetTop; | 
						
						
							|  | 				const offsetTop2 = i < scrollItems.length - 1 ? scrollItems[i+1].offsetTop : offsetTop1 + 2; | 
						
						
							|  | 				if ( scrollTop >= offsetTop1 &&  scrollTop < offsetTop2 ) { | 
						
						
							|  | 					const start = parseInt(scrollItems[i].getAttribute('start')); | 
						
						
							|  | 					const end = parseInt(scrollItems[i].getAttribute('end')); | 
						
						
							|  | 					if ( this._start != start ) { | 
						
						
							|  | 						this._start = start | 
						
						
							|  | 						this._end = end | 
						
						
							|  | 						if ( this.footerShow ) {//如果页面位置发生改变,则更新footer | 
						
						
							|  | 							const newFooter = await this._createFooterDom(start) | 
						
						
							|  | 							const oldFooter = this._wrapperEl.getElementsByClassName('whole-reader-footer')[0] | 
						
						
							|  | 							this._wrapperEl.removeChild(oldFooter) | 
						
						
							|  | 							this._wrapperEl.appendChild(newFooter) | 
						
						
							|  | 						} | 
						
						
							|  | 						this._pageChange() | 
						
						
							|  | 					} | 
						
						
							|  | 				} | 
						
						
							|  | 			} | 
						
						
							|  | 			if ( Math.ceil(this._scrollerEl.scrollTop + this._scrollerEl.offsetHeight) >= this._scrollerEl.scrollHeight ) {//触底 | 
						
						
							|  | 				if ( this._updownloading ) return; | 
						
						
							|  | 				this._updownloading = true; | 
						
						
							|  | 				const end = parseInt(this._scrollerEl.lastChild.getAttribute('end')); | 
						
						
							|  | 				if ( end < this._contents.length - 1 ) { | 
						
						
							|  | 					const page = this._computedNextText(end) | 
						
						
							|  | 					const item = this._createTextDom(page) | 
						
						
							|  | 					this._scrollerEl.appendChild(item) | 
						
						
							|  | 					if ( this._scrollerEl.getElementsByClassName('whole-scroll-reader-content-text').length > 3 ) this._scrollerEl.removeChild(this._scrollerEl.firstChild); | 
						
						
							|  | 					this._scrollerEl.scrollTop = this._scrollerEl.scrollHeight - this._scrollerEl.lastChild.offsetHeight - this._scrollerEl.offsetHeight; | 
						
						
							|  | 				} else this._eventCallback.ended && this._eventCallback.ended()//后翻页完成事件 | 
						
						
							|  | 				this._updownloading = false; | 
						
						
							|  | 			} | 
						
						
							|  | 			if ( this._scrollerEl.scrollTop <= 0 ) {//触顶 | 
						
						
							|  | 				if ( this._updownloading ) return | 
						
						
							|  | 				this._updownloading = true; | 
						
						
							|  | 				const start = parseInt(this._scrollerEl.firstChild.getAttribute('start')); | 
						
						
							|  | 				if ( start > 0 ) { | 
						
						
							|  | 					const page = this._computedPrevText(start) | 
						
						
							|  | 					const item = this._createTextDom(page) | 
						
						
							|  | 					this._scrollerEl.insertBefore(item, this._scrollerEl.firstChild) | 
						
						
							|  | 					this._scrollerEl.scrollTop = item.offsetHeight | 
						
						
							|  | 					if ( this._scrollerEl.getElementsByClassName('whole-scroll-reader-content-text').length > 3 ) this._scrollerEl.removeChild(this._scrollerEl.lastChild); | 
						
						
							|  | 				} else this._eventCallback.started && this._eventCallback.started()//前翻页完成事件 | 
						
						
							|  | 				this._updownloading = false; | 
						
						
							|  | 			} | 
						
						
							|  | 		}catch(e){ | 
						
						
							|  | 			//TODO handle the exception | 
						
						
							|  | 		} | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //翻页模式触摸开始事件 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'_touchstart',{ | 
						
						
							|  |     value:function(e){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader._touchstart is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  | 		if ( this._pageWating ) return; | 
						
						
							|  | 		this._touchTimer = window.setTimeout(() => { | 
						
						
							|  | 			this._touchTime = 200; | 
						
						
							|  | 		}, 200) | 
						
						
							|  | 		const touch = e.touches[0]; | 
						
						
							|  | 		this._touchstartX = touch.pageX; | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //翻页模式触摸滑动事件 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'_touchmove',{ | 
						
						
							|  |     value:function(e){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader._touchmove is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  | 		if ( this._touchstartX == 0 || (this.pageType != 'real' && this.pageType != 'cover') ) return; | 
						
						
							|  | 		const touch = e.touches[0] | 
						
						
							|  | 		if ( this._pageEl ) { | 
						
						
							|  | 			const height = this._viewHeight / 2; | 
						
						
							|  | 			const maxDeg = height / 5; | 
						
						
							|  | 			const rotateZ = this._pageDirection == 'next' ? ((touch.pageY - height) / maxDeg) : -((touch.pageY - height) / maxDeg); | 
						
						
							|  | 			this._moveX = touch.pageX - this._touchstartX; | 
						
						
							|  | 			if ( this._pageDirection == 'next' ) this._moveX > 0 ? this._moveX = 0 : null | 
						
						
							|  | 			else this._moveX < 0 ? this._moveX = 0 : null | 
						
						
							|  | 			this._pageAnimation(this._moveX, rotateZ); | 
						
						
							|  | 		} else { | 
						
						
							|  | 			if ( touch.pageX < this._touchstartX ) { | 
						
						
							|  | 				this._pageEl = this._getPageActived(0); | 
						
						
							|  | 				this._pageDirection = 'next' | 
						
						
							|  | 			} else { | 
						
						
							|  | 				this._pageEl = this._getPageActived(-1); | 
						
						
							|  | 				this._pageDirection = 'prev' | 
						
						
							|  | 			} | 
						
						
							|  | 		} | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //翻页模式触摸处理事件 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'_touchaction',{ | 
						
						
							|  |     value:function(e){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader._touchaction is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  | 		window.clearTimeout(this._touchTimer); | 
						
						
							|  | 		this._touchTimer = null | 
						
						
							|  | 		if ( this._touchstartX == 0 ) return; | 
						
						
							|  | 		if ( !this._pageEl && this._touchTime < 200 && (!this.unableClickPage || this.pageType == 'none') ) { | 
						
						
							|  | 			//获取点击位置,判断向哪里翻页 | 
						
						
							|  | 			if (this._touchstartX > (this._viewWidth / 4) * 3) {//向右翻页 | 
						
						
							|  | 				this._pageEl = this._getPageActived(0); | 
						
						
							|  | 				this._pageDirection = 'next' | 
						
						
							|  | 			} | 
						
						
							|  | 			if (this._touchstartX < (this._viewWidth / 4)) {//向左翻页 | 
						
						
							|  | 				this._pageEl = this._getPageActived(-1); | 
						
						
							|  | 				this._pageDirection = 'prev' | 
						
						
							|  | 			} | 
						
						
							|  | 		} | 
						
						
							|  | 		this._touchstartX = 0 | 
						
						
							|  | 		if ( this._pageEl ) { | 
						
						
							|  | 			this._pageWating = true; | 
						
						
							|  | 			if ( this._touchTime < 200 ) { | 
						
						
							|  | 				const duration = (this.pageType == 'real' || this.pageType == 'cover') ? 200 : 0 | 
						
						
							|  | 				const value = this._pageDirection == 'next' ? 1 : -1; | 
						
						
							|  | 				this._pageDuration(duration); | 
						
						
							|  | 				this._pageAnimation(-value * this._viewWidth); | 
						
						
							|  | 				setTimeout(() => { | 
						
						
							|  | 					this._changePageActived(value); | 
						
						
							|  | 					this._resetPageMove(); | 
						
						
							|  | 				}, duration + 50) | 
						
						
							|  | 			} else { | 
						
						
							|  | 				const duration = (this.pageType == 'real' || this.pageType == 'cover') ? 100 : 0 | 
						
						
							|  | 				if ( Math.abs(this._moveX) >= this._viewWidth / 4 ) { | 
						
						
							|  | 					const value = this._pageDirection == 'next' ? 1 : -1; | 
						
						
							|  | 					this._pageDuration(duration); | 
						
						
							|  | 					this._pageAnimation(-value * this._viewWidth); | 
						
						
							|  | 					setTimeout(() => { | 
						
						
							|  | 						this._changePageActived(value); | 
						
						
							|  | 						this._resetPageMove(); | 
						
						
							|  | 					}, duration + 50) | 
						
						
							|  | 				} else { | 
						
						
							|  | 					this._pageDuration(duration); | 
						
						
							|  | 					this._pageAnimation(0); | 
						
						
							|  | 					setTimeout(() => { | 
						
						
							|  | 						this._resetPageMove(); | 
						
						
							|  | 					}, duration + 50) | 
						
						
							|  | 				} | 
						
						
							|  | 			} | 
						
						
							|  | 		} else { | 
						
						
							|  | 			this._touchTime = 0 | 
						
						
							|  | 		} | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //设置翻页对象动画效果 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'_pageAnimation',{ | 
						
						
							|  |     value:function(moveX, rotateZ = 0, el){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader._pageAnimation is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  | 		const lateX = this._pageDirection == 'next' ? moveX : moveX - this._viewWidth; | 
						
						
							|  | 		const pageEl = el || this._pageEl; | 
						
						
							|  | 		pageEl.box.style.transform = `translateX(${lateX}px)`; | 
						
						
							|  | 		pageEl.box.style.boxShadow = el ? '' : '10px 10px 20px rgba(0,0,0,.2)'; | 
						
						
							|  | 		pageEl.content.style.transform = this.pageType == 'real' ? `translateX(${-lateX}px)` : pageEl.content.style.transform; | 
						
						
							|  | 		pageEl.bg.style.transform = this.pageType == 'real' ? `translate(${lateX}px, -50%) rotateZ(${rotateZ}deg)` : pageEl.bg.style.transform; | 
						
						
							|  | 		pageEl.shadow.style.boxShadow = '0 0 60px ' + (this.pageType == 'real' ? Math.abs(lateX) > 30 ? 30 : Math.abs(lateX) : 0) + 'px rgba(0,0,0,0.5)'; | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //设置翻页对象动画时间 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'_pageDuration',{ | 
						
						
							|  |     value:function(duration){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader._pageDuration is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  | 		this._pageEl.box.style.transition = duration > 0 ? 'transform ' + duration + 'ms' : ''; | 
						
						
							|  | 		this._pageEl.content.style.transition = duration > 0 ? 'transform ' + duration + 'ms' : ''; | 
						
						
							|  | 		this._pageEl.bg.style.transition = duration > 0 ? 'transform ' + duration + 'ms' : ''; | 
						
						
							|  | 		this._pageEl.shadow.style.transition = duration > 0 ? 'box-shadow ' + duration + 'ms' : ''; | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //获取翻页对象 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'_getPageActived',{ | 
						
						
							|  |     value:function(value){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader._getPageActived is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  | 		const boxs = this.container.getElementsByClassName('whole-flip-reader-page-item'); | 
						
						
							|  | 		for ( let i = 0; i < boxs.length; i++ ) { | 
						
						
							|  | 			if ( boxs[i].getAttribute('class').indexOf('whole-flip-reader-page-item-actived') > 1 ) { | 
						
						
							|  | 				if ( boxs[i + value + 1] && boxs[i + value] ) { | 
						
						
							|  | 					return { | 
						
						
							|  | 						box: boxs[i + value], | 
						
						
							|  | 						content: boxs[i + value].getElementsByClassName('whole-flip-reader-page-item-content')[0], | 
						
						
							|  | 						bg: boxs[i + value].getElementsByClassName('whole-flip-reader-page-item-bg')[0], | 
						
						
							|  | 						shadow: boxs[i + value].getElementsByClassName('whole-flip-reader-page-item-shadow')[0] | 
						
						
							|  | 					}; | 
						
						
							|  | 				} | 
						
						
							|  | 			} | 
						
						
							|  | 		} | 
						
						
							|  | 		if ( value < 0 ) this._eventCallback.started && this._eventCallback.started()//前翻页完成事件 | 
						
						
							|  | 		else this._eventCallback.ended && this._eventCallback.ended()//后翻页完成事件 | 
						
						
							|  | 		return false; | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //改变翻页对象 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'_changePageActived',{ | 
						
						
							|  |     value:async function(value){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader._changePageActived is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  | 		const boxs = this.container.getElementsByClassName('whole-flip-reader-page-item'); | 
						
						
							|  | 		let index = -1 | 
						
						
							|  | 		for ( let i = 0; i < boxs.length; i++ ) if ( boxs[i].getAttribute('class').indexOf('page-item-actived') > -1 ) index = i | 
						
						
							|  | 		boxs[index].setAttribute('class', boxs[index].getAttribute('class').replace('whole-flip-reader-page-item-actived', '')); | 
						
						
							|  | 		boxs[index + value].setAttribute('class', boxs[index + value].getAttribute('class') + ' whole-flip-reader-page-item-actived'); | 
						
						
							|  | 		this._start = parseInt(boxs[index + value].getAttribute('start')); | 
						
						
							|  | 		this._end = parseInt(boxs[index + value].getAttribute('end')); | 
						
						
							|  | 		this._pageChange() | 
						
						
							|  | 		if ( value < 0 && !boxs[index + value - 1] ) {//向前翻页 | 
						
						
							|  | 			if ( this._updownloading ) return; | 
						
						
							|  | 			this._updownloading = true; | 
						
						
							|  | 			const start = parseInt(this._wrapperEl.firstChild.getAttribute('start')); | 
						
						
							|  | 			if ( start > 0 ) { | 
						
						
							|  | 				const page = this._computedPrevText(start) | 
						
						
							|  | 				const item = await this._createPageDom(page) | 
						
						
							|  | 				this._wrapperEl.insertBefore(item, this._wrapperEl.firstChild) | 
						
						
							|  | 				if ( this._wrapperEl.getElementsByClassName('whole-flip-reader-page-item').length > 3 ) this._wrapperEl.removeChild(this._wrapperEl.lastChild); | 
						
						
							|  | 			} | 
						
						
							|  | 			this._updownloading = false; | 
						
						
							|  | 		} | 
						
						
							|  | 		if ( value > 0 && !boxs[index + value + 1] ) {//向后翻页 | 
						
						
							|  | 			if ( this._updownloading ) return; | 
						
						
							|  | 			this._updownloading = true; | 
						
						
							|  | 			const end = parseInt(this._wrapperEl.lastChild.getAttribute('end')); | 
						
						
							|  | 			if ( end < this._contents.length - 1 ) { | 
						
						
							|  | 				const page = this._computedNextText(end) | 
						
						
							|  | 				const item = await this._createPageDom(page) | 
						
						
							|  | 				this._wrapperEl.appendChild(item) | 
						
						
							|  | 				if ( this._wrapperEl.getElementsByClassName('whole-flip-reader-page-item').length > 3 ) this._wrapperEl.removeChild(this._wrapperEl.firstChild); | 
						
						
							|  | 			} | 
						
						
							|  | 			this._updownloading = false; | 
						
						
							|  | 		} | 
						
						
							|  | 		if ( value < 0 && boxs[index + value].getAttribute('end') != boxs[index + value + 1].getAttribute('start') ) this.refresh()//如果是向前翻页并且前一页结束位置和当前页开始位置不对应时刷新页面 | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //页面改变事件 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'_pageChange',{ | 
						
						
							|  |     value:function(){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader._changePageActived is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  | 		const text = this._contents.slice(this._start, this._end) | 
						
						
							|  | 		this._eventCallback.change && this._eventCallback.change({ | 
						
						
							|  | 			start: this._start, | 
						
						
							|  | 			end: this._end, | 
						
						
							|  | 			contents: text, | 
						
						
							|  | 			content: text.join('') | 
						
						
							|  | 		}); | 
						
						
							|  | 		if ( this.pageType != 'scroll' ) this._startAutoplay() | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //重置翻页事件 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'_resetPageMove',{ | 
						
						
							|  |     value:function(){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader._resetPageMove is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  | 		this._pageDuration(0) | 
						
						
							|  | 		if ( this._pageEl ) this._pageEl.box.style.boxShadow = '' | 
						
						
							|  | 		this._pageWating = false; | 
						
						
							|  | 		this._moveX = 0; | 
						
						
							|  | 		this._pageEl = ''; | 
						
						
							|  | 		this._pageDirection = 'next'; | 
						
						
							|  | 		this._touchTime = 0; | 
						
						
							|  | 		this._touchstartX = 0; | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | }) | 
						
						
							|  | //将内容转化为数组 | 
						
						
							|  | Object.defineProperty(Wholereader.prototype,'_contentToArr',{ | 
						
						
							|  |     value:function(){ | 
						
						
							|  |         if(!(this instanceof Wholereader)){//那么相反 不是正常调用的就是错误的调用 | 
						
						
							|  |            throw new TypeError("TypeError: Wholereader._contentToArr is not a constructor") | 
						
						
							|  |         } | 
						
						
							|  | 		const arr = this.split ? [] : this.content.split('') | 
						
						
							|  | 		if ( arr.length == 0 ) {//如果传入了分隔符 | 
						
						
							|  | 			let chars = ''//临时字符串 | 
						
						
							|  | 			for ( let i = 0; i < this.content.length; i++ ) { | 
						
						
							|  | 				const char = this.content.charAt(i) | 
						
						
							|  | 				if ( /\r|\n/.test(char) ) {//如果是换行符 | 
						
						
							|  | 					if ( chars ) arr.push(chars)//直接将先前存储的字符push进数组 | 
						
						
							|  | 					arr.push(char)//再将标签push进数组 | 
						
						
							|  | 					chars = ''//清空临时字符串 | 
						
						
							|  | 				} else if ( this.split.indexOf(char) > -1 ) {//如果是分隔符 | 
						
						
							|  | 					chars += char//将分隔符加入字符串 | 
						
						
							|  | 					arr.push(chars)//将字符串push进数组 | 
						
						
							|  | 					chars = ''//清空临时字符串 | 
						
						
							|  | 				} else {//其余字符先存着 | 
						
						
							|  | 					chars += char | 
						
						
							|  | 				} | 
						
						
							|  | 			} | 
						
						
							|  | 		} | 
						
						
							|  | 		return arr | 
						
						
							|  |     }, | 
						
						
							|  |     enumerable:false | 
						
						
							|  | })
 |