BackTop.vue 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. <template>
  2. <div class="back-top" @click="onClickBackTop" v-show="isShowBackTopBtn">
  3. <slot>
  4. <div class="back-top__default">回到顶部</div>
  5. </slot>
  6. </div>
  7. </template>
  8. <script>
  9. // const TWEEN = require('@tweenjs/tween.js')
  10. export default({
  11. props: {
  12. targetId: {
  13. type: String,
  14. required: true,
  15. },
  16. triggerDistance: {
  17. type: Number,
  18. default: 200,
  19. }
  20. },
  21. data() {
  22. return {
  23. target: null,
  24. isShowBackTopBtn: false,
  25. isBackingTop: false,
  26. }
  27. },
  28. methods: {
  29. onClickBackTop() {
  30. if (this.isBackingTop) {
  31. return
  32. }
  33. this.isBackingTop = true
  34. // const tweenTarget = {
  35. // scrollTop: this.target.scrollTop
  36. // }
  37. // new TWEEN.Tween(tweenTarget)
  38. // .to({scrollTop: 0}, 800)
  39. // .easing(TWEEN.Easing.Quartic.Out)
  40. // .onUpdate(() => {
  41. // this.target.scrollTop = tweenTarget.scrollTop
  42. // })
  43. // .onComplete(() => {
  44. // this.isBackingTop = false
  45. // })
  46. // .start()
  47. // const animate = (time) => {
  48. // if (this.isBackingTop) {
  49. // requestAnimationFrame(animate)
  50. // TWEEN.update(time)
  51. // }
  52. // }
  53. // requestAnimationFrame(animate)
  54. // 不想引入tween.js的话,可以用这段简单的匀速滚动代码
  55. const startTime = Date.now()
  56. const totalScroll = this.target.scrollTop
  57. const fn = () => {
  58. if (this.target.scrollTop === 0) {
  59. this.isBackingTop = false
  60. return
  61. }
  62. const nowTime = Date.now()
  63. const assumeScrollTop = totalScroll - (nowTime - startTime) * totalScroll / 500
  64. this.target.scrollTop = assumeScrollTop > 0 ? assumeScrollTop : 0
  65. requestAnimationFrame(fn)
  66. }
  67. requestAnimationFrame(fn)
  68. },
  69. onTargetScroll: globalUtils.debounce(function(e) {
  70. if (this.isBackingTop) {
  71. return
  72. }
  73. if (e.target.scrollTop >= this.triggerDistance) {
  74. this.isShowBackTopBtn = true
  75. } else {
  76. this.isShowBackTopBtn = false
  77. }
  78. }),
  79. },
  80. mounted() {
  81. this.target = document.getElementById(this.targetId)
  82. if (this.target) {
  83. this.target.addEventListener('scroll', this.onTargetScroll, {
  84. passive: true,
  85. })
  86. }
  87. },
  88. unmounted() {
  89. if (this.target) {
  90. this.target.removeEventListener('scroll', this.onTargetScroll, {
  91. passive: true,
  92. })
  93. }
  94. }
  95. })
  96. </script>
  97. <style scoped lang="less">
  98. .back-top__default {
  99. cursor: pointer;
  100. }
  101. </style>