Skip to content

Commit

Permalink
feat(scroll): smarter scroll behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
Mate Solymosi committed Feb 26, 2020
1 parent dc43d3c commit 2964305
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 15 deletions.
21 changes: 18 additions & 3 deletions src/core/event/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,26 @@
import { isMobile } from '../util/env';
import { body, on } from '../util/dom';
import * as sidebar from './sidebar';
import { scrollIntoView } from './scroll';
import { scrollIntoView, scroll2Top } from './scroll';

export function eventMixin(proto) {
proto.$resetEvents = function() {
scrollIntoView(this.route.path, this.route.query.id);
proto.$resetEvents = function(source) {
const { auto2top } = this.config;

(() => {
// Rely on the browser's scroll auto-restoration when going back or forward
if (source === 'history') {
return;
}
// Scroll to ID if specified
if (this.route.query.id) {
scrollIntoView(this.route.path, this.route.query.id);
}
// Scroll to top if a link was clicked and auto2top is enabled
if (source === 'navigate') {
auto2top && scroll2Top(auto2top);
}
})();

if (this.config.loadNavbar) {
sidebar.getAndActive(this.router, 'nav');
Expand Down
4 changes: 2 additions & 2 deletions src/core/fetch/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export function fetchMixin(proto) {
}
};

proto.$fetch = function(cb = noop) {
proto.$fetch = function(cb = noop, $resetEvents = this.$resetEvents.bind(this)) {
const done = () => {
callHook(this, 'doneEach');
cb();
Expand All @@ -160,7 +160,7 @@ export function fetchMixin(proto) {
done();
} else {
this._fetch(() => {
this.$resetEvents();
$resetEvents();
done();
});
}
Expand Down
6 changes: 2 additions & 4 deletions src/core/render/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { getAndActive, sticky } from '../event/sidebar';
import { getPath, isAbsolutePath } from '../router/util';
import { isMobile, inBrowser } from '../util/env';
import { isPrimitive } from '../util/core';
import { scrollActiveSidebar, scroll2Top } from '../event/scroll';
import { scrollActiveSidebar } from '../event/scroll';
import { Compiler } from './compiler';
import * as tpl from './tpl';
import { prerenderEmbed } from './embed';
Expand Down Expand Up @@ -123,7 +123,7 @@ export function renderMixin(proto) {
};

proto._bindEventOnRendered = function(activeEl) {
const { autoHeader, auto2top } = this.config;
const { autoHeader } = this.config;

scrollActiveSidebar(this.router);

Expand All @@ -136,8 +136,6 @@ export function renderMixin(proto) {
dom.before(main, wrapper.children[0]);
}
}

auto2top && scroll2Top(auto2top);
};

proto._renderNav = function(text) {
Expand Down
20 changes: 19 additions & 1 deletion src/core/router/history/hash.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,25 @@ export class HashHistory extends History {
}

onchange(cb = noop) {
on('hashchange', cb);
// The hashchange event does not tell us if it originated from
// a clicked link or by moving back/forward in the history;
// therefore we set a `navigating` flag when a link is clicked
// to be able to tell these two scenarios apart
let navigating = false;

on('click', e => {
const el = e.target.tagName === 'A' ? e.target : e.target.parentNode;

if (el.tagName === 'A' && !/_blank/.test(el.target)) {
navigating = true;
}
});

on('hashchange', e => {
const source = navigating ? 'navigate' : 'history';
navigating = false;
cb({ event: e, source });
});
}

normalize() {
Expand Down
6 changes: 4 additions & 2 deletions src/core/router/history/html5.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@ export class HTML5History extends History {
e.preventDefault();
const url = el.href;
window.history.pushState({ key: url }, '', url);
cb();
cb({ event: e, source: 'navigate' });
}
});

on('popstate', cb);
on('popstate', e => {
cb({ event: e, source: 'history' });
});
}

/**
Expand Down
7 changes: 4 additions & 3 deletions src/core/router/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { supportsPushState } from '../util/env';
import * as dom from '../util/dom';
import { HashHistory } from './history/hash';
import { HTML5History } from './history/html5';
import { noop } from '../util/core';

export function routerMixin(proto) {
proto.route = {};
Expand Down Expand Up @@ -31,16 +32,16 @@ export function initRouter(vm) {
lastRoute = vm.route;

// eslint-disable-next-line no-unused-vars
router.onchange(_ => {
router.onchange(params => {
updateRender(vm);
vm._updateRender();

if (lastRoute.path === vm.route.path) {
vm.$resetEvents();
vm.$resetEvents(params.source);
return;
}

vm.$fetch();
vm.$fetch(noop, vm.$resetEvents.bind(vm, params.source));
lastRoute = vm.route;
});
}

0 comments on commit 2964305

Please sign in to comment.