Skip to content

Commit e88c9f0

Browse files
author
Henrik Ruscon
committed
fix scrollspy anchors
1 parent ed6ad03 commit e88c9f0

File tree

1 file changed

+36
-49
lines changed

1 file changed

+36
-49
lines changed

src/components/ScrollSpy.vue

Lines changed: 36 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,16 @@ export default {
5252
5353
mounted() {
5454
this.initItems()
55-
this.initAnchors()
55+
this.removeActiveClass()
56+
this.currentItem = this.getItemInsideWindow()
57+
58+
if (this.currentItem) this.currentItem.classList.add(this.activeClass)
5659
5760
this.scrollContainer.addEventListener('scroll', this.onScroll)
5861
},
5962
6063
updated() {
6164
this.initItems()
62-
this.initAnchors()
6365
},
6466
6567
beforeDestroy() {
@@ -70,26 +72,24 @@ export default {
7072
onScroll(event) {
7173
this.currentItem = this.getItemInsideWindow()
7274
73-
if (this.currentItem) {
74-
if (this.currentItem !== this.lastActiveItem) {
75-
const { hash } = this.currentItem
75+
if (this.currentItem && this.currentItem !== this.lastActiveItem) {
76+
const { hash } = this.currentItem
7677
77-
this.removeActiveClass()
78-
this.lastActiveItem = this.currentItem
78+
this.removeActiveClass()
79+
this.lastActiveItem = this.currentItem
7980
80-
this.currentItem.classList.add(this.activeClass)
81+
this.currentItem.classList.add(this.activeClass)
8182
82-
const currentParent = this.currentItem.closest(this.itemClass + 's')
83-
.previousElementSibling.classList
83+
const currentParent = this.currentItem.closest(this.itemClass + 's')
84+
.previousElementSibling.classList
8485
85-
if (currentParent.contains(this.itemClass.substr(1))) {
86-
currentParent.add(this.activeParentClass)
87-
}
86+
if (currentParent.contains(this.itemClass.substr(1))) {
87+
currentParent.add(this.activeParentClass)
88+
}
8889
89-
this.currentItem.scrollIntoView({ block: 'end', inline: 'nearest' })
90+
this.currentItem.scrollIntoView({ block: 'end', inline: 'nearest' })
9091
91-
this.updateHash(hash)
92-
}
92+
this.updateHash(hash)
9393
}
9494
},
9595
@@ -109,64 +109,51 @@ export default {
109109
110110
initItems() {
111111
this.items = this.$el.querySelectorAll(this.itemClass)
112+
this.anchors = this.scrollContainer.querySelectorAll('a[href*="#"]')
112113
113114
this.items.forEach(item => {
114115
item.addEventListener('click', this.handleClick)
115116
})
116117
117-
this.removeActiveClass()
118-
this.currentItem = this.getItemInsideWindow()
119-
120-
if (this.currentItem) this.currentItem.classList.add(this.activeClass)
121-
},
122-
123-
initAnchors() {
124-
this.anchors = this.scrollContainer.querySelectorAll('a[href*="#"]')
125-
126118
this.anchors.forEach(anchor => {
127-
anchor.addEventListener('click', this.handleAnchorClick)
119+
anchor.addEventListener('click', this.handleClick)
128120
})
129121
},
130122
131123
handleClick(event) {
132124
event.preventDefault()
133125
134-
const { hash } = event.currentTarget
135-
const target = document.getElementById(hash.substr(1))
126+
const isAnchor = !event.currentTarget.classList.contains(this.itemClass.substr(1))
127+
const target = event.currentTarget
128+
const hash = target.hash
129+
const item = isAnchor
130+
? document.querySelector(`a[href='${hash.substr(0, hash.indexOf('-'))}']`)
131+
: target
132+
const section = document.getElementById(hash.substr(1))
136133
137134
this.scrollContainer.removeEventListener('scroll', this.onScroll)
138135
139136
this.removeActiveClass()
140-
event.currentTarget.classList.add(this.activeClass)
141137
142-
const currentParent = event.currentTarget.closest(this.itemClass + 's')
143-
.previousElementSibling.classList
138+
item.classList.add(this.activeClass)
139+
140+
const parent = item.closest(this.itemClass + 's').previousElementSibling.classList
144141
145-
if (currentParent.contains(this.itemClass.substr(1))) {
146-
currentParent.add(this.activeParentClass)
142+
if (parent.contains(this.itemClass.substr(1))) {
143+
parent.add(this.activeParentClass)
147144
}
148145
149-
event.currentTarget.scrollIntoView({
146+
item.scrollIntoView({
150147
behavior: 'instant',
151148
block: 'end',
152149
inline: 'nearest'
153150
})
154-
target.scrollIntoView({ behavior: 'instant' })
155151
156-
this.scrollContainer.addEventListener('scroll', this.onScroll)
157-
158-
this.updateHash(hash)
159-
},
160-
161-
handleAnchorClick(event) {
162-
event.preventDefault()
163-
164-
const { hash } = event.currentTarget
165-
const target = document.getElementById(hash.substr(1))
166-
167-
this.scrollContainer.removeEventListener('scroll', this.onScroll)
168-
169-
target.scrollIntoView({ behavior: 'instant' })
152+
section.scrollIntoView({
153+
behavior: 'instant',
154+
block: 'start',
155+
inline: 'nearest'
156+
})
170157
171158
// Scrolling lacks callback & is async
172159
setTimeout(() => {

0 commit comments

Comments
 (0)