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
| <template>
| <div :style="{height:height+'px',zIndex:zIndex}">
| <div
| :class="className"
| :style="{top:(isSticky ? stickyTop +'px' : ''),zIndex:zIndex,position:position,width:width,height:height+'px'}"
| >
| <slot>
| <div>sticky</div>
| </slot>
| </div>
| </div>
| </template>
|
| <script>
| export default {
| name: 'Sticky',
| props: {
| stickyTop: {
| type: Number,
| default: 0
| },
| zIndex: {
| type: Number,
| default: 1
| },
| className: {
| type: String,
| default: ''
| }
| },
| data() {
| return {
| active: false,
| position: '',
| width: undefined,
| height: undefined,
| isSticky: false
| }
| },
| mounted() {
| this.height = this.$el.getBoundingClientRect().height
| window.addEventListener('scroll', this.handleScroll)
| window.addEventListener('resize', this.handleResize)
| },
| activated() {
| this.handleScroll()
| },
| destroyed() {
| window.removeEventListener('scroll', this.handleScroll)
| window.removeEventListener('resize', this.handleResize)
| },
| methods: {
| sticky() {
| if (this.active) {
| return
| }
| this.position = 'fixed'
| this.active = true
| this.width = this.width + 'px'
| this.isSticky = true
| },
| handleReset() {
| if (!this.active) {
| return
| }
| this.reset()
| },
| reset() {
| this.position = ''
| this.width = 'auto'
| this.active = false
| this.isSticky = false
| },
| handleScroll() {
| const width = this.$el.getBoundingClientRect().width
| this.width = width || 'auto'
| const offsetTop = this.$el.getBoundingClientRect().top
| if (offsetTop < this.stickyTop) {
| this.sticky()
| return
| }
| this.handleReset()
| },
| handleResize() {
| if (this.isSticky) {
| this.width = this.$el.getBoundingClientRect().width + 'px'
| }
| }
| }
| }
| </script>
|
|