-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpointerScroll.js
executable file
·94 lines (85 loc) · 2.3 KB
/
pointerScroll.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// flow scored from vue select thanks Jeff!
export default {
watch: {
pointer() {
this.maybeAdjustScroll()
}
},
data() {
return {
pointer: -1
}
},
methods: {
/**
* Adjust the scroll position of the dropdown list
* if the current pointer is outside of the
* overflow bounds.
* @returns {*}
*/
maybeAdjustScroll() {
const pixelsToPointerTop = this.pixelsToPointerTop()
const pixelsToPointerBottom = this.pixelsToPointerBottom()
if (pixelsToPointerTop <= this.viewport().top) {
return this.scrollTo(pixelsToPointerTop)
} else if (pixelsToPointerBottom >= this.viewport().bottom) {
return this.scrollTo(this.viewport().top + this.pointerHeight())
}
},
/**
* The distance in pixels from the top of the dropdown
* list to the top of the current pointer element.
* @returns {number}
*/
pixelsToPointerTop() {
let pixelsToPointerTop = 0
if (!this.$refs.options) {
return 0
}
for (let i = 0; i < this.pointer; i++) {
pixelsToPointerTop += this.$refs.options.children[i].offsetHeight
}
return pixelsToPointerTop
},
/**
* The distance in pixels from the top of the dropdown
* list to the bottom of the current pointer element.
* @returns {*}
*/
pixelsToPointerBottom() {
return this.pixelsToPointerTop() + this.pointerHeight()
},
/**
* The offsetHeight of the current pointer element.
* @returns {number}
*/
pointerHeight() {
const element = this.$refs.options
? this.$refs.options.children[this.pointer]
: false
return element ? element.offsetHeight : 0
},
/**
* The currently viewable portion of the options.
* @returns {{top: (string|*|number), bottom: *}}
*/
viewport() {
return {
top: this.$refs.options ? this.$refs.options.scrollTop : 0,
bottom: this.$refs.options
? this.$refs.options.offsetHeight + this.$refs.options.scrollTop
: 0
}
},
/**
* Scroll the options to a given position.
* @param position
* @returns {*}
*/
scrollTo(position) {
return this.$refs.options
? (this.$refs.options.scrollTop = position)
: null
}
}
}