back-to-top.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // [z-paging]点击返回顶部view模块
  2. import u from '.././z-paging-utils'
  3. export default {
  4. props: {
  5. // 自动显示点击返回顶部按钮,默认为否
  6. autoShowBackToTop: {
  7. type: Boolean,
  8. default: u.gc('autoShowBackToTop', false)
  9. },
  10. // 点击返回顶部按钮显示/隐藏的阈值(滚动距离),单位为px,默认为400rpx
  11. backToTopThreshold: {
  12. type: [Number, String],
  13. default: u.gc('backToTopThreshold', '400rpx')
  14. },
  15. // 点击返回顶部按钮的自定义图片地址,默认使用z-paging内置的图片
  16. backToTopImg: {
  17. type: String,
  18. default: u.gc('backToTopImg', '')
  19. },
  20. // 点击返回顶部按钮返回到顶部时是否展示过渡动画,默认为是
  21. backToTopWithAnimate: {
  22. type: Boolean,
  23. default: u.gc('backToTopWithAnimate', true)
  24. },
  25. // 点击返回顶部按钮与底部的距离,注意添加单位px或rpx,默认为160rpx
  26. backToTopBottom: {
  27. type: [Number, String],
  28. default: u.gc('backToTopBottom', '160rpx')
  29. },
  30. // 点击返回顶部按钮的自定义样式
  31. backToTopStyle: {
  32. type: Object,
  33. default: u.gc('backToTopStyle', {}),
  34. },
  35. // iOS点击顶部状态栏、安卓双击标题栏时,滚动条返回顶部,只支持竖向,默认为是
  36. enableBackToTop: {
  37. type: Boolean,
  38. default: u.gc('enableBackToTop', true)
  39. },
  40. },
  41. data() {
  42. return {
  43. // 点击返回顶部的class
  44. backToTopClass: 'zp-back-to-top zp-back-to-top-hide',
  45. // 上次点击返回顶部的时间
  46. lastBackToTopShowTime: 0,
  47. // 点击返回顶部显示的class是否在展示中,使得按钮展示/隐藏过度效果更自然
  48. showBackToTopClass: false,
  49. }
  50. },
  51. computed: {
  52. backToTopThresholdUnitConverted() {
  53. return u.addUnit(this.backToTopThreshold, this.unit);
  54. },
  55. backToTopBottomUnitConverted() {
  56. return u.addUnit(this.backToTopBottom, this.unit);
  57. },
  58. finalEnableBackToTop() {
  59. return this.usePageScroll ? false : this.enableBackToTop;
  60. },
  61. finalBackToTopThreshold() {
  62. return u.convertToPx(this.backToTopThresholdUnitConverted);
  63. },
  64. finalBackToTopStyle() {
  65. const backToTopStyle = this.backToTopStyle;
  66. if (!backToTopStyle.bottom) {
  67. backToTopStyle.bottom = this.windowBottom + u.convertToPx(this.backToTopBottomUnitConverted) + 'px';
  68. }
  69. if(!backToTopStyle.position){
  70. backToTopStyle.position = this.usePageScroll ? 'fixed': 'absolute';
  71. }
  72. return backToTopStyle;
  73. },
  74. finalBackToTopClass() {
  75. return `${this.backToTopClass} zp-back-to-top-${this.unit}`;
  76. }
  77. },
  78. methods: {
  79. // 点击了返回顶部
  80. _backToTopClick() {
  81. let callbacked = false;
  82. this.$emit('backToTopClick', toTop => {
  83. (toTop === undefined || toTop === true) && this._handleToTop();
  84. callbacked = true;
  85. });
  86. // 如果用户没有禁止默认的返回顶部事件,则触发滚动到顶部
  87. this.$nextTick(() => {
  88. !callbacked && this._handleToTop();
  89. })
  90. },
  91. // 处理滚动到顶部
  92. _handleToTop() {
  93. !this.backToTopWithAnimate && this._checkShouldShowBackToTop(0);
  94. this.scrollToTop(this.backToTopWithAnimate);
  95. },
  96. // 判断是否要显示返回顶部按钮
  97. _checkShouldShowBackToTop(scrollTop) {
  98. if (!this.autoShowBackToTop) {
  99. this.showBackToTopClass = false;
  100. return;
  101. }
  102. if (scrollTop > this.finalBackToTopThreshold) {
  103. if (!this.showBackToTopClass) {
  104. // 记录当前点击返回顶部按钮显示的class生效了
  105. this.showBackToTopClass = true;
  106. this.lastBackToTopShowTime = new Date().getTime();
  107. // 当滚动到需要展示返回顶部的阈值内,则延迟300毫秒展示返回到顶部按钮
  108. u.delay(() => {
  109. this.backToTopClass = 'zp-back-to-top zp-back-to-top-show';
  110. }, 300)
  111. }
  112. } else {
  113. // 如果当前点击返回顶部按钮显示的class是生效状态并且滚动小于触发阈值,则隐藏返回顶部按钮
  114. if (this.showBackToTopClass) {
  115. this.backToTopClass = 'zp-back-to-top zp-back-to-top-hide';
  116. u.delay(() => {
  117. this.showBackToTopClass = false;
  118. }, new Date().getTime() - this.lastBackToTopShowTime < 500 ? 0 : 300)
  119. }
  120. }
  121. },
  122. }
  123. }