Skip to content

Commit 023c899

Browse files
sigerelloyyx990803
authored andcommitted
add offset feature to scrollBehavior
1 parent cc5b64d commit 023c899

File tree

3 files changed

+27
-6
lines changed

3 files changed

+27
-6
lines changed

examples/scroll-behavior/app.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ const Bar = {
1010
<div>
1111
bar
1212
<div style="height:500px"></div>
13-
<p id="anchor">Anchor</p>
13+
<p id="anchor" style="height:500px">Anchor</p>
14+
<p id="anchor2">Anchor2</p>
1415
</div>
1516
`
1617
}
@@ -29,6 +30,11 @@ const scrollBehavior = (to, from, savedPosition) => {
2930
// scroll to anchor by returning the selector
3031
if (to.hash) {
3132
position.selector = to.hash
33+
34+
// specify offset of the element
35+
if (to.hash === '#anchor2') {
36+
position.offset = { y: 100 }
37+
}
3238
}
3339
// check if any matched route config has meta that requires scrolling to top
3440
if (to.matched.some(m => m.meta.scrollToTop)) {
@@ -64,6 +70,7 @@ new Vue({
6470
<li><router-link to="/foo">/foo</router-link></li>
6571
<li><router-link to="/bar">/bar</router-link></li>
6672
<li><router-link to="/bar#anchor">/bar#anchor</router-link></li>
73+
<li><router-link to="/bar#anchor2">/bar#anchor2</router-link></li>
6774
</ul>
6875
<router-view class="view"></router-view>
6976
</div>

src/util/scroll.js

+13-4
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ export function handleScroll (
4545
if (isObject && typeof shouldScroll.selector === 'string') {
4646
const el = document.querySelector(shouldScroll.selector)
4747
if (el) {
48-
position = getElementPosition(el)
48+
let offset = shouldScroll.offset && typeof shouldScroll.offset === 'object' ? shouldScroll.offset : {}
49+
offset = normalizeOffset(offset)
50+
position = getElementPosition(el, offset)
4951
} else if (isValidPosition(shouldScroll)) {
5052
position = normalizePosition(shouldScroll)
5153
}
@@ -76,13 +78,13 @@ function getScrollPosition (): ?Object {
7678
}
7779
}
7880

79-
function getElementPosition (el: Element): Object {
81+
function getElementPosition (el: Element, offset: Object): Object {
8082
const docEl: any = document.documentElement
8183
const docRect = docEl.getBoundingClientRect()
8284
const elRect = el.getBoundingClientRect()
8385
return {
84-
x: elRect.left - docRect.left,
85-
y: elRect.top - docRect.top
86+
x: elRect.left - docRect.left - offset.x,
87+
y: elRect.top - docRect.top - offset.y
8688
}
8789
}
8890

@@ -97,6 +99,13 @@ function normalizePosition (obj: Object): Object {
9799
}
98100
}
99101

102+
function normalizeOffset (obj: Object): Object {
103+
return {
104+
x: isNumber(obj.x) ? obj.x : 0,
105+
y: isNumber(obj.y) ? obj.y : 0
106+
}
107+
}
108+
100109
function isNumber (v: any): boolean {
101110
return typeof v === 'number'
102111
}

test/e2e/specs/scroll-behavior.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module.exports = {
33
browser
44
.url('http://localhost:8080/scroll-behavior/')
55
.waitForElementVisible('#app', 1000)
6-
.assert.count('li a', 4)
6+
.assert.count('li a', 5)
77
.assert.containsText('.view', 'home')
88

99
.execute(function () {
@@ -47,6 +47,11 @@ module.exports = {
4747
.assert.evaluate(function () {
4848
return document.getElementById('anchor').getBoundingClientRect().top < 1
4949
}, null, 'scroll to anchor')
50+
51+
.click('li:nth-child(5) a')
52+
.assert.evaluate(function () {
53+
return document.getElementById('anchor2').getBoundingClientRect().top < 101
54+
}, null, 'scroll to anchor with offset')
5055
.end()
5156
}
5257
}

0 commit comments

Comments
 (0)