1
// Directives
2 1
import { Scroll } from '../../directives'
3

4
// Utilities
5 1
import { consoleWarn } from '../../util/console'
6

7
// Types
8 1
import Vue from 'vue'
9

10
/**
11
 * Scrollable
12
 *
13
 * Used for monitoring scrolling and
14
 * invoking functions based upon
15
 * scrolling thresholds being
16
 * met.
17
 */
18
/* @vue/component */
19 1
export default Vue.extend({
20
  name: 'scrollable',
21

22
  directives: { Scroll },
23

24
  props: {
25
    scrollTarget: String,
26
    scrollThreshold: [String, Number],
27
  },
28

29 1
  data: () => ({
30
    currentScroll: 0,
31
    currentThreshold: 0,
32
    isActive: false,
33
    isScrollingUp: false,
34
    previousScroll: 0,
35
    savedScroll: 0,
36
    target: null as Element | null,
37
  }),
38

39
  computed: {
40
    /**
41
     * A computed property that returns
42
     * whether scrolling features are
43
     * enabled or disabled
44
     */
45 1
    canScroll (): boolean {
46 1
      return typeof window !== 'undefined'
47
    },
48
    /**
49
     * The threshold that must be met before
50
     * thresholdMet function is invoked
51
     */
52 1
    computedScrollThreshold (): number {
53 1
      return this.scrollThreshold
54 1
        ? Number(this.scrollThreshold)
55 1
        : 300
56
    },
57
  },
58

59
  watch: {
60 1
    isScrollingUp () {
61 1
      this.savedScroll = this.savedScroll || this.currentScroll
62
    },
63 1
    isActive () {
64 1
      this.savedScroll = 0
65
    },
66
  },
67

68 1
  mounted () {
69 1
    if (this.scrollTarget) {
70 1
      this.target = document.querySelector(this.scrollTarget)
71

72 1
      if (!this.target) {
73 1
        consoleWarn(`Unable to locate element with identifier ${this.scrollTarget}`, this)
74
      }
75
    }
76
  },
77

78
  methods: {
79 1
    onScroll () {
80 1
      if (!this.canScroll) return
81

82 1
      this.previousScroll = this.currentScroll
83 1
      this.currentScroll = this.target
84 1
        ? this.target.scrollTop
85 1
        : window.pageYOffset
86

87 1
      this.isScrollingUp = this.currentScroll < this.previousScroll
88 1
      this.currentThreshold = Math.abs(this.currentScroll - this.computedScrollThreshold)
89

90 1
      this.$nextTick(() => {
91 1
        if (
92
          Math.abs(this.currentScroll - this.savedScroll) >
93
          this.computedScrollThreshold
94 1
        ) this.thresholdMet()
95
      })
96
    },
97
    /**
98
     * The method invoked when
99
     * scrolling in any direction
100
     * has exceeded the threshold
101
     */
102 1
    thresholdMet () { /* noop */ },
103
  },
104
})

Read our documentation on viewing source code .

Loading