index.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import { VantComponent } from '../common/component';
  2. import { pageScrollMixin } from '../mixins/page-scroll';
  3. const ROOT_ELEMENT = '.van-sticky';
  4. VantComponent({
  5. props: {
  6. zIndex: {
  7. type: Number,
  8. value: 99
  9. },
  10. offsetTop: {
  11. type: Number,
  12. value: 0,
  13. observer: 'onScroll'
  14. },
  15. disabled: {
  16. type: Boolean,
  17. observer: 'onScroll'
  18. },
  19. container: {
  20. type: null,
  21. observer: 'onScroll'
  22. }
  23. },
  24. mixins: [
  25. pageScrollMixin(function (event) {
  26. this.onScroll(event);
  27. })
  28. ],
  29. data: {
  30. height: 0,
  31. fixed: false,
  32. transform: 0
  33. },
  34. mounted() {
  35. this.onScroll();
  36. },
  37. methods: {
  38. onScroll({ scrollTop } = {}) {
  39. const { container, offsetTop, disabled } = this.data;
  40. if (disabled) {
  41. this.setDataAfterDiff({
  42. fixed: false,
  43. transform: 0
  44. });
  45. return;
  46. }
  47. this.scrollTop = scrollTop || this.scrollTop;
  48. if (typeof container === 'function') {
  49. Promise.all([this.getRect(ROOT_ELEMENT), this.getContainerRect()]).then(([root, container]) => {
  50. if (offsetTop + root.height > container.height + container.top) {
  51. this.setDataAfterDiff({
  52. fixed: false,
  53. transform: container.height - root.height
  54. });
  55. }
  56. else if (offsetTop >= root.top) {
  57. this.setDataAfterDiff({
  58. fixed: true,
  59. height: root.height,
  60. transform: 0
  61. });
  62. }
  63. else {
  64. this.setDataAfterDiff({ fixed: false, transform: 0 });
  65. }
  66. });
  67. return;
  68. }
  69. this.getRect(ROOT_ELEMENT).then((root) => {
  70. if (offsetTop >= root.top) {
  71. this.setDataAfterDiff({ fixed: true, height: root.height });
  72. this.transform = 0;
  73. }
  74. else {
  75. this.setDataAfterDiff({ fixed: false });
  76. }
  77. });
  78. },
  79. setDataAfterDiff(data) {
  80. wx.nextTick(() => {
  81. const diff = Object.keys(data).reduce((prev, key) => {
  82. if (data[key] !== this.data[key]) {
  83. prev[key] = data[key];
  84. }
  85. return prev;
  86. }, {});
  87. this.setData(diff);
  88. this.$emit('scroll', {
  89. scrollTop: this.scrollTop,
  90. isFixed: data.fixed || this.data.fixed
  91. });
  92. });
  93. },
  94. getContainerRect() {
  95. const nodesRef = this.data.container();
  96. return new Promise(resolve => nodesRef.boundingClientRect(resolve).exec());
  97. }
  98. }
  99. });