From bccecec6af2e788bd2960cfa67df6fc892b8cf0b Mon Sep 17 00:00:00 2001 From: Oleksandr Sergiienko Date: Fri, 9 Jun 2017 17:59:07 +0300 Subject: [PATCH] add offset feature to scrollBehavior --- examples/scroll-behavior/app.js | 9 ++++++++- src/util/scroll.js | 17 +++++++++++++---- test/e2e/specs/scroll-behavior.js | 7 ++++++- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/examples/scroll-behavior/app.js b/examples/scroll-behavior/app.js index 617ce6a4f..af555e8b5 100644 --- a/examples/scroll-behavior/app.js +++ b/examples/scroll-behavior/app.js @@ -10,7 +10,8 @@ const Bar = {
bar
-

Anchor

+

Anchor

+

Anchor2

` } @@ -29,6 +30,11 @@ const scrollBehavior = (to, from, savedPosition) => { // scroll to anchor by returning the selector if (to.hash) { position.selector = to.hash + + // specify offset of the element + if (to.hash === '#anchor2') { + position.offset = { y: 100 } + } } // check if any matched route config has meta that requires scrolling to top if (to.matched.some(m => m.meta.scrollToTop)) { @@ -64,6 +70,7 @@ new Vue({
  • /foo
  • /bar
  • /bar#anchor
  • +
  • /bar#anchor2
  • diff --git a/src/util/scroll.js b/src/util/scroll.js index c7a6a7805..18b62ee18 100644 --- a/src/util/scroll.js +++ b/src/util/scroll.js @@ -45,7 +45,9 @@ export function handleScroll ( if (isObject && typeof shouldScroll.selector === 'string') { const el = document.querySelector(shouldScroll.selector) if (el) { - position = getElementPosition(el) + let offset = shouldScroll.offset && typeof shouldScroll.offset === 'object' ? shouldScroll.offset : {} + offset = normalizeOffset(offset) + position = getElementPosition(el, offset) } else if (isValidPosition(shouldScroll)) { position = normalizePosition(shouldScroll) } @@ -76,13 +78,13 @@ function getScrollPosition (): ?Object { } } -function getElementPosition (el: Element): Object { +function getElementPosition (el: Element, offset: Object): Object { const docEl: any = document.documentElement const docRect = docEl.getBoundingClientRect() const elRect = el.getBoundingClientRect() return { - x: elRect.left - docRect.left, - y: elRect.top - docRect.top + x: elRect.left - docRect.left - offset.x, + y: elRect.top - docRect.top - offset.y } } @@ -97,6 +99,13 @@ function normalizePosition (obj: Object): Object { } } +function normalizeOffset (obj: Object): Object { + return { + x: isNumber(obj.x) ? obj.x : 0, + y: isNumber(obj.y) ? obj.y : 0 + } +} + function isNumber (v: any): boolean { return typeof v === 'number' } diff --git a/test/e2e/specs/scroll-behavior.js b/test/e2e/specs/scroll-behavior.js index 4955ef146..7075f681b 100644 --- a/test/e2e/specs/scroll-behavior.js +++ b/test/e2e/specs/scroll-behavior.js @@ -3,7 +3,7 @@ module.exports = { browser .url('http://localhost:8080/scroll-behavior/') .waitForElementVisible('#app', 1000) - .assert.count('li a', 4) + .assert.count('li a', 5) .assert.containsText('.view', 'home') .execute(function () { @@ -47,6 +47,11 @@ module.exports = { .assert.evaluate(function () { return document.getElementById('anchor').getBoundingClientRect().top < 1 }, null, 'scroll to anchor') + + .click('li:nth-child(5) a') + .assert.evaluate(function () { + return document.getElementById('anchor2').getBoundingClientRect().top < 101 + }, null, 'scroll to anchor with offset') .end() } }