|
|
- <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>
|