四零语境前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

126 lines
4.8 KiB

  1. export default {
  2. computed: {
  3. currentProgress () {
  4. return this.pages[this.current]?.progress || 0
  5. },
  6. currentTitle () {
  7. return this.pages[this.current]?.title || this.title
  8. },
  9. currentTotal () {
  10. return this.pages[this.current]?.total || 0
  11. },
  12. currentPage () {
  13. return this.pages[this.current]?.current || 0
  14. }
  15. },
  16. methods: {
  17. //渲染页面
  18. scrollRender ({chapter, current, start = 0}) {
  19. if ( chapter ) {//如果传入章节内容
  20. const index = this.chapters.findIndex(c => c.index == chapter.index)//是否已经包含相同章节
  21. if (index > -1) this.chapters[index] = chapter//如果包含则更新
  22. else this.chapters.push(chapter)//否则添加新章节
  23. }
  24. current = parseInt(current || 0)//强制转换类型为int
  25. start = parseInt(start)//强制转换类型为int
  26. this.pages = [{index: current, type: 'loading'}]//显示loading
  27. this.current = 0//重置current
  28. const cgs = this.chapters.filter(c => c.index == current || c.index == current - 1 || c.index == current + 1)//筛选出符合条件的三个章节内容
  29. let index = 0, arr = []
  30. const computedId = this.getComputedId()
  31. this.computeds.push(computedId)
  32. const computedIndex = this.computeds.indexOf(computedId)
  33. this.$nextTick(function () {
  34. setTimeout(() => {
  35. const handle = () => {
  36. this.$refs.computed[computedIndex] && this.$refs.computed[computedIndex].start({
  37. chapter: cgs[index],
  38. success: pages => {
  39. arr = arr.concat(pages)
  40. if ( index < cgs.length - 1 ) {
  41. index++
  42. this.$nextTick(function () { handle() })
  43. } else {
  44. this.computeds.splice(computedIndex, 1)
  45. this.pages = this.handlePages(arr)
  46. const pageIndex = this.pages.findIndex(p => start >= p.start && start < p.end && p.index == current )//定位章节
  47. if ( pageIndex == -1 ) this.current = this.pages.findIndex(p => start >= p.end && p.index == current )//定位章节
  48. else this.current = pageIndex
  49. this.$nextTick(function () {
  50. this.$refs.scroll.resetRefresh()
  51. this.$refs.scroll.scrollToIndex(this.current)
  52. this.handleChange({current: this.current, detail: this.pages[this.current] })
  53. this.$nextTick(function () {
  54. this.autoplaySync = this.autoplay
  55. })
  56. })
  57. }
  58. }
  59. })
  60. }
  61. handle()
  62. }, 100)
  63. })
  64. },
  65. //翻页改变事件
  66. async handleScroll (e) {
  67. const scrollTop = e.detail.scrollTop
  68. const scrollHeight = e.detail.scrollHeight
  69. if ( !this.scrolling ) {
  70. try{
  71. this.scrolling = true
  72. const rate = Math.floor(scrollTop / this.contentHeight)
  73. let maybe = this.pages[rate] ? rate : this.pages.length-1
  74. let top = -1
  75. while ( top < 0 && maybe < this.pages.length - 1 ) {
  76. const itemRect = await this.$refs.scroll.getItemRect(maybe)
  77. top = itemRect.top
  78. top < 0 ? maybe++ : null
  79. }
  80. const current = top >= 0 ? maybe : this.pages.length - 1
  81. if ( current != this.current ) {
  82. this.handleChange({current: current, detail: this.pages[current]})
  83. this.$refs.footer && this.$refs.footer.refresh()
  84. }
  85. this.scrolling = false
  86. }catch(e){
  87. this.scrolling = false
  88. }
  89. }
  90. },
  91. //渲染下一章节
  92. handleScrollLoadRender (status, chapter, callback, isPrev) {
  93. if ( status == 'success' ) {//获取内容成功
  94. const nowIndex = isPrev ? this.pages[0].index : this.pages[this.pages.length-1].index
  95. const chapterIndex = this.chapters.findIndex(c => c.index == chapter.index)//是否已经包含相同章节
  96. if (chapterIndex > -1) this.chapters[chapterIndex] = chapter//如果包含则更新
  97. else this.chapters.push(chapter)//否则添加新章节
  98. const computedId = this.getComputedId()
  99. this.computeds.push(computedId)
  100. const computedIndex = this.computeds.indexOf(computedId)
  101. this.$nextTick(function () {
  102. setTimeout(() => {
  103. this.$refs.computed[computedIndex] && this.$refs.computed[computedIndex].start({
  104. chapter: chapter,
  105. success: p => {
  106. this.computeds.splice(computedIndex, 1)
  107. callback && callback( (chapter.isStart || chapter.isEnd) ? 'end' : status)//关闭加载动画
  108. const pages = isPrev ? p.concat(this.pages) : this.pages.concat(p)//添加新计算的章节内容
  109. this.pages = pages//渲染章节内容
  110. if ( isPrev ) {//如果是加载上一章节需要重新定位
  111. this.$nextTick(function () {
  112. this.current = pages.findIndex(page => page.index == nowIndex)//定位页面
  113. this.$refs.scroll.scrollToIndex(this.current)//刷新翻页组件
  114. })
  115. }
  116. this.chapterLoading = false//关闭章节加载等待
  117. }
  118. })
  119. }, 100)
  120. })
  121. } else {
  122. this.chapterLoading = false//关闭章节加载等待
  123. callback && callback(status)//关闭加载动画
  124. }
  125. }
  126. }
  127. }