Skip to content

Commit

Permalink
Scroll to top on nav, but not back/forward
Browse files Browse the repository at this point in the history
Related to Issue #32
  • Loading branch information
BobChao87 committed Aug 27, 2021
1 parent 2ce8d16 commit 0c0beef
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 0 deletions.
5 changes: 5 additions & 0 deletions layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ export default Vue.extend({
head(): Required<Pick<MetaInfo, 'htmlAttrs'|'link'|'meta'>> {
return this.$nuxtI18nHead({ addSeoAttributes: true });
},
watch: {
$route(): void {
this.$scroll();
},
},
mounted(): void {
// Provide calls to this.$gtag here to update Analytics
},
Expand Down
1 change: 1 addition & 0 deletions nuxt.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export default {
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
'plugins': [
{ src: '~/plugins/google-gtag.client.ts', mode: 'client' },
{ src: '~/plugins/scroll.client.ts', mode: 'client' },
],

// Auto import components: https://go.nuxtjs.dev/config-components
Expand Down
40 changes: 40 additions & 0 deletions plugins/scroll.client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Plugin } from '@nuxt/types';

declare module 'vue/types/vue' {
interface Vue {
$scroll(): void;
}
}

/**
* How does this work? A good question. It may be buggy.
*
* When user navigation occurs, history is written to the browser to be used by
* the back/forward buttons. This history maintains an immutable state for each
* page. We are referencing one of the values of that state stack, the key. In
* Chrome and Firefox, this /appears/ to be a monotonically increasing
* string-encoded number. Possibly the number of milliseconds since the
* page/website was first navigated to. More testing is required.
*
* We detect when the value on the page we're on is higher than the largest
* value we've seen before. If it is, it's a new page, and we scroll. If it's
* not, we rely on the user's browser settings to decide to scroll to their
* previous position or not, depending on preferences.
*
* This function is called universally by watching to see when $route changes
* in the layout for the pages. If it's broken, first confirm your page's
* layout does call this.$scroll() inside of watch on $route.
*/
const scrollPlugin: Plugin = (_, inject) => {
let historyKeyMax = 0;

inject('scroll', () => {
const historyKey = +history.state.key;
if (historyKeyMax < historyKey) {
historyKeyMax = historyKey;
window.scrollTo(0, 0);
}
});
};

export default scrollPlugin;

0 comments on commit 0c0beef

Please sign in to comment.