diff --git a/docs/configuration.md b/docs/configuration.md index b42c0ab00..11797c794 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -575,3 +575,16 @@ window.$docsify = { ``` > Note: The options with fallbackLanguages didn't work with the `notFoundPage` options. + +## topMargin + +- type: `Number` +- default: `0` + +Adds a space on top when scrolling content page to reach the selected section. This is useful in case you have a _sticky-header_ layout and you want to align anchors to the end of your header. + +```js +window.$docsify = { + topMargin: 90, // default: 0 +}; +``` \ No newline at end of file diff --git a/packages/docsify-server-renderer/index.js b/packages/docsify-server-renderer/index.js index dfd06c9cb..8f70f78d7 100644 --- a/packages/docsify-server-renderer/index.js +++ b/packages/docsify-server-renderer/index.js @@ -1,13 +1,13 @@ import { readFileSync } from 'fs'; import { resolve, basename } from 'path'; +import resolvePathname from 'resolve-pathname'; +import debug from 'debug'; +import fetch from 'node-fetch'; import { AbstractHistory } from '../../src/core/router/history/abstract'; import { Compiler } from '../../src/core/render/compiler'; import { isAbsolutePath } from '../../src/core/router/util'; import * as tpl from '../../src/core/render/tpl'; import { prerenderEmbed } from '../../src/core/render/embed'; -import resolvePathname from 'resolve-pathname'; -import debug from 'debug'; -import fetch from 'node-fetch'; function cwd(...args) { return resolve(process.cwd(), ...args); diff --git a/src/core/config.js b/src/core/config.js index ed64e6718..c35179059 100644 --- a/src/core/config.js +++ b/src/core/config.js @@ -33,6 +33,7 @@ export default function() { routerMode: 'hash', noCompileLinks: [], relativePath: false, + topMargin: 0, }, window.$docsify ); diff --git a/src/core/event/scroll.js b/src/core/event/scroll.js index 2a3b16cae..ae6d3d47f 100644 --- a/src/core/event/scroll.js +++ b/src/core/event/scroll.js @@ -1,7 +1,8 @@ -import { isMobile } from '../util/env'; -import * as dom from '../util/dom'; import Tweezer from 'tweezer.js'; import cssEscape from 'css.escape'; +import { isMobile } from '../util/env'; +import * as dom from '../util/dom'; +import config from '../config'; const nav = {}; let hoverOver = false; @@ -9,7 +10,7 @@ let scroller = null; let enableScrollEvent = true; let coverHeight = 0; -function scrollTo(el) { +function scrollTo(el, offset = 0) { if (scroller) { scroller.stop(); } @@ -17,7 +18,7 @@ function scrollTo(el) { enableScrollEvent = false; scroller = new Tweezer({ start: window.pageYOffset, - end: el.getBoundingClientRect().top + window.pageYOffset, + end: el.getBoundingClientRect().top + window.pageYOffset - offset, duration: 500, }) .on('tick', v => window.scrollTo(0, v)) @@ -142,9 +143,9 @@ export function scrollIntoView(path, id) { if (!id) { return; } - + const topMargin = config().topMargin; const section = dom.find('#' + cssEscape(id)); - section && scrollTo(section); + section && scrollTo(section, topMargin); const li = nav[getNavKey(path, id)]; const sidebar = dom.getNode('.sidebar'); diff --git a/src/core/global-api.js b/src/core/global-api.js index 102ded28e..fd5269ae1 100644 --- a/src/core/global-api.js +++ b/src/core/global-api.js @@ -1,10 +1,10 @@ +import marked from 'marked'; +import prism from 'prismjs'; import * as util from './util'; import * as dom from './util/dom'; import { Compiler } from './render/compiler'; import { slugify } from './render/slugify'; import { get } from './fetch/ajax'; -import marked from 'marked'; -import prism from 'prismjs'; export default function() { window.Docsify = { diff --git a/src/core/render/compiler.js b/src/core/render/compiler.js index d00b3e209..4916aae5e 100644 --- a/src/core/render/compiler.js +++ b/src/core/render/compiler.js @@ -1,3 +1,4 @@ +import marked from 'marked'; import { isAbsolutePath, getPath, getParentPath } from '../router/util'; import { isFn, merge, cached, isPrimitive } from '../util/core'; import { tree as treeTpl } from './tpl'; @@ -10,7 +11,6 @@ import { paragraphCompiler } from './compiler/paragraph'; import { taskListCompiler } from './compiler/taskList'; import { taskListItemCompiler } from './compiler/taskListItem'; import { linkCompiler } from './compiler/link'; -import marked from 'marked'; const cachedLinks = {}; diff --git a/src/core/render/embed.js b/src/core/render/embed.js index 2b5826f15..0e7c7e131 100644 --- a/src/core/render/embed.js +++ b/src/core/render/embed.js @@ -1,6 +1,6 @@ +import stripIndent from 'strip-indent'; import { get } from '../fetch/ajax'; import { merge } from '../util/core'; -import stripIndent from 'strip-indent'; const cached = {}; diff --git a/src/core/render/index.js b/src/core/render/index.js index ca8e8f56b..70d4005cd 100644 --- a/src/core/render/index.js +++ b/src/core/render/index.js @@ -1,4 +1,5 @@ /* eslint-disable no-unused-vars */ +import tinydate from 'tinydate'; import * as dom from '../util/dom'; import cssVars from '../util/polyfill/css-vars'; import { callHook } from '../init/lifecycle'; @@ -10,7 +11,6 @@ import { scrollActiveSidebar, scroll2Top } from '../event/scroll'; import { Compiler } from './compiler'; import * as tpl from './tpl'; import { prerenderEmbed } from './embed'; -import tinydate from 'tinydate'; function executeScript() { const script = dom diff --git a/test/unit/base.test.js b/test/unit/base.test.js index 736b70ac6..ed050424a 100644 --- a/test/unit/base.test.js +++ b/test/unit/base.test.js @@ -2,8 +2,8 @@ require = require('esm')( module /* , options */ ); /* eslint-disable-line no-global-assign */ -const { History } = require('../../src/core/router/history/base'); const { expect } = require('chai'); +const { History } = require('../../src/core/router/history/base'); class MockHistory extends History { parse(path) { diff --git a/test/unit/render.test.js b/test/unit/render.test.js index c65d4c958..60ed5e0a0 100644 --- a/test/unit/render.test.js +++ b/test/unit/render.test.js @@ -1,5 +1,5 @@ -const { init, expectSameDom } = require('../_helper'); const { expect } = require('chai'); +const { init, expectSameDom } = require('../_helper'); describe('render', function() { it('important content (tips)', async function() { diff --git a/test/unit/util.test.js b/test/unit/util.test.js index e4e8a0e3b..9dadf28a3 100644 --- a/test/unit/util.test.js +++ b/test/unit/util.test.js @@ -2,8 +2,8 @@ require = require('esm')( module /* , options */ ); /* eslint-disable-line no-global-assign */ -const { resolvePath } = require('../../src/core/router/util'); const { expect } = require('chai'); +const { resolvePath } = require('../../src/core/router/util'); describe('router/util', function() { it('resolvePath', async function() {