mirror of
https://github.com/wahyd4/docsify.git
synced 2026-08-09 13:26:34 +10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1fdfaf0b6b | ||
|
|
fe33e2d506 | ||
|
|
6463dd3bae | ||
|
|
299c31dff9 | ||
|
|
aa1d84b513 | ||
|
|
14a4c2f77d | ||
|
|
e58c17fdc6 | ||
|
|
8b719238e6 | ||
|
|
7f0b1089c0 | ||
|
|
2610e25040 | ||
|
|
ec53f1e307 | ||
|
|
670cc68a28 | ||
|
|
844ba3e022 | ||
|
|
9092b22246 | ||
|
|
d175ba6913 | ||
|
|
2574778605 | ||
|
|
44a255103c |
@@ -1,3 +1,6 @@
|
||||
sudo: false
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.yarn-cache
|
||||
language: node_js
|
||||
node_js: stable
|
||||
|
||||
+1
-1
@@ -8,5 +8,5 @@
|
||||
<body class="">
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
<script src="/lib/docsify.js" data-repo="qingwei-li/docsify" data-sidebar-toggle data-router data-load-sidebar></script>
|
||||
<script src="/lib/docsify.js" data-repo="qingwei-li/docsify" data-auto2top data-sidebar-toggle data-router></script>
|
||||
</html>
|
||||
|
||||
@@ -1,3 +1,26 @@
|
||||
## 1.1.2
|
||||
### Bug fixes
|
||||
- fix failed `auto2top` in mobile
|
||||
|
||||
|
||||
## 1.1.1
|
||||
### Bug fixes
|
||||
- Optimize progress bar
|
||||
|
||||
## 1.1.0
|
||||
## Features
|
||||
- Add progress bar
|
||||
- Add `auto2top` option for hash router
|
||||
|
||||
## 1.0.3
|
||||
### Bug fixes
|
||||
- Fix cache
|
||||
|
||||
## 1.0.2
|
||||
### Bug fixes
|
||||
- Fix binding events bug, fixed #24
|
||||
- Fix regular expression, fixed #23
|
||||
|
||||
## 1.0.1
|
||||
### Bug fixes
|
||||
- `img` style
|
||||
|
||||
@@ -60,3 +60,8 @@ These open-source projects are using docsify to generate their sites. Pull reque
|
||||
|
||||
## License
|
||||
MIT
|
||||
|
||||
## Support on Beerpay
|
||||
Hey dude! Help me out for a couple of :beers:!
|
||||
|
||||
[](https://beerpay.io/QingWei-Li/docsify) [](https://beerpay.io/QingWei-Li/docsify?focus=wish)
|
||||
@@ -220,3 +220,13 @@ Hash router. You can replace `404.html` with `index.html`.
|
||||
```html
|
||||
<script src="/lib/docsify.js" data-router></script>
|
||||
```
|
||||
|
||||
### auto2top
|
||||
|
||||
Scroll to the top on changing hash.
|
||||
|
||||
|
||||
```html
|
||||
<script src="/lib/docsify.js" data-auto2top></script>
|
||||
```
|
||||
|
||||
|
||||
@@ -221,3 +221,13 @@ Sidebar 开关按钮
|
||||
```html
|
||||
<script src="/lib/docsify.js" data-router></script>
|
||||
```
|
||||
|
||||
### auto2top
|
||||
|
||||
切换路由时自动跳转到页面顶部
|
||||
|
||||
|
||||
```html
|
||||
<script src="/lib/docsify.js" data-auto2top></script>
|
||||
```
|
||||
|
||||
|
||||
+194
-110
@@ -4,11 +4,12 @@ var Docsify = (function () {
|
||||
/**
|
||||
* Simple ajax
|
||||
* @param {String} url
|
||||
* @param {String} [method=get]
|
||||
* @param {String} [method=GET]
|
||||
* @param {Function} [loading] handle loading
|
||||
* @return {Promise}
|
||||
*/
|
||||
function load (url, method) {
|
||||
if ( method === void 0 ) method = 'get';
|
||||
function load (url, method, loading) {
|
||||
if ( method === void 0 ) method = 'GET';
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
||||
@@ -19,13 +20,18 @@ function load (url, method) {
|
||||
then: function (success, error) {
|
||||
if ( error === void 0 ) error = function () {};
|
||||
|
||||
if (loading) {
|
||||
xhr.addEventListener('progress', loading);
|
||||
xhr.addEventListener('loaded', loading);
|
||||
}
|
||||
xhr.addEventListener('error', error);
|
||||
xhr.addEventListener('load', function (ref) {
|
||||
var target = ref.target;
|
||||
|
||||
target.status >= 400 ? error(target) : success(target.response);
|
||||
});
|
||||
}
|
||||
},
|
||||
abort: function () { return xhr.readyState !== 4 && xhr.abort(); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,6 +105,111 @@ function getRoute () {
|
||||
return route
|
||||
}
|
||||
|
||||
function isMobile () {
|
||||
return /mobile/i.test(navigator.userAgent)
|
||||
}
|
||||
|
||||
/**
|
||||
* Active sidebar when scroll
|
||||
* @link https://buble.surge.sh/
|
||||
*/
|
||||
function scrollActiveSidebar () {
|
||||
if (isMobile()) { return }
|
||||
|
||||
var anchors = document.querySelectorAll('.anchor');
|
||||
var nav = {};
|
||||
var lis = document.querySelectorAll('.sidebar li');
|
||||
var active = null;
|
||||
|
||||
for (var i = 0, len = lis.length; i < len; i += 1) {
|
||||
var li = lis[i];
|
||||
var href = li.querySelector('a').getAttribute('href');
|
||||
|
||||
if (href !== '/') { href = href.match(/#([^#]+)$/g)[0].slice(1); }
|
||||
|
||||
nav[href] = li;
|
||||
}
|
||||
|
||||
function highlight () {
|
||||
for (var i = 0, len = anchors.length; i < len; i += 1) {
|
||||
var node = anchors[i].parentNode;
|
||||
var bcr = node.getBoundingClientRect();
|
||||
|
||||
if (bcr.top < 10 && bcr.bottom > 10) {
|
||||
var li = nav[node.id];
|
||||
|
||||
if (!li || li === active) { return }
|
||||
if (active) { active.setAttribute('class', ''); }
|
||||
|
||||
li.setAttribute('class', 'active');
|
||||
active = li;
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var dom = document.querySelector('main .content');
|
||||
dom.removeEventListener('scroll', highlight);
|
||||
dom.addEventListener('scroll', highlight);
|
||||
highlight();
|
||||
}
|
||||
|
||||
function scrollIntoView () {
|
||||
var id = window.location.hash.match(/#[^#\/]+$/g);
|
||||
if (!id || !id.length) { return }
|
||||
var section = document.querySelector(id[0]);
|
||||
|
||||
if (section) { section.scrollIntoView(); }
|
||||
}
|
||||
|
||||
/**
|
||||
* Acitve link
|
||||
*/
|
||||
function activeLink (dom, activeParent) {
|
||||
var host = window.location.href;
|
||||
|
||||
dom = typeof dom === 'object' ? dom : document.querySelector(dom);
|
||||
if (!dom) { return
|
||||
|
||||
; }[].slice.call(dom.querySelectorAll('a')).forEach(function (node) {
|
||||
if (node.href === host) {
|
||||
activeParent
|
||||
? node.parentNode.setAttribute('class', 'active')
|
||||
: node.setAttribute('class', 'active');
|
||||
} else {
|
||||
activeParent
|
||||
? node.parentNode.removeAttribute('class')
|
||||
: node.removeAttribute('class');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* sidebar toggle
|
||||
*/
|
||||
function bindToggle (dom) {
|
||||
dom = typeof dom === 'object' ? dom : document.querySelector(dom);
|
||||
if (!dom) { return }
|
||||
var body = document.body;
|
||||
|
||||
dom.addEventListener('click', function () { return body.classList.toggle('close'); });
|
||||
|
||||
if (!/mobile/i.test(navigator.userAgent)) { return }
|
||||
document.querySelector('aside').addEventListener('click', function (event) {
|
||||
body.classList.toggle('close');
|
||||
});
|
||||
}
|
||||
|
||||
var cacheContentDOM;
|
||||
function scroll2Top () {
|
||||
if (!cacheContentDOM) {
|
||||
var dom = isMobile() ? 'body' : 'section.content';
|
||||
cacheContentDOM = document.querySelector(dom);
|
||||
}
|
||||
cacheContentDOM.scrollTop = 0;
|
||||
}
|
||||
|
||||
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
||||
|
||||
|
||||
@@ -2240,100 +2351,8 @@ function tree (toc, tpl) {
|
||||
return tpl
|
||||
}
|
||||
|
||||
/**
|
||||
* Active sidebar when scroll
|
||||
* @link https://buble.surge.sh/
|
||||
*/
|
||||
function scrollActiveSidebar () {
|
||||
if (/mobile/i.test(navigator.userAgent)) { return }
|
||||
|
||||
var anchors = document.querySelectorAll('.anchor');
|
||||
var nav = {};
|
||||
var lis = document.querySelectorAll('.sidebar li');
|
||||
var active = null;
|
||||
|
||||
for (var i = 0, len = lis.length; i < len; i += 1) {
|
||||
var li = lis[i];
|
||||
var href = li.querySelector('a').getAttribute('href');
|
||||
|
||||
if (href !== '/') { href = href.match(/#([^#]+)$/g)[0].slice(1); }
|
||||
|
||||
nav[href] = li;
|
||||
}
|
||||
|
||||
function highlight () {
|
||||
for (var i = 0, len = anchors.length; i < len; i += 1) {
|
||||
var node = anchors[i].parentNode;
|
||||
var bcr = node.getBoundingClientRect();
|
||||
|
||||
if (bcr.top < 10 && bcr.bottom > 10) {
|
||||
var li = nav[node.id];
|
||||
|
||||
if (!li || li === active) { return }
|
||||
if (active) { active.setAttribute('class', ''); }
|
||||
|
||||
li.setAttribute('class', 'active');
|
||||
active = li;
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
document.querySelector('main .content').addEventListener('scroll', highlight);
|
||||
highlight();
|
||||
|
||||
function scrollIntoView () {
|
||||
var id = window.location.hash.match(/#[^#\/]+$/g);
|
||||
if (!id || !id.length) { return }
|
||||
var section = document.querySelector(id[0]);
|
||||
|
||||
if (section) { section.scrollIntoView(); }
|
||||
}
|
||||
|
||||
window.addEventListener('hashchange', scrollIntoView);
|
||||
scrollIntoView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Acitve link
|
||||
*/
|
||||
function activeLink (dom, activeParent) {
|
||||
var host = window.location.href;
|
||||
|
||||
dom = typeof dom === 'object' ? dom : document.querySelector(dom);
|
||||
if (!dom) { return
|
||||
|
||||
; }[].slice.call(dom.querySelectorAll('a')).forEach(function (node) {
|
||||
if (node.href === host) {
|
||||
activeParent
|
||||
? node.parentNode.setAttribute('class', 'active')
|
||||
: node.setAttribute('class', 'active');
|
||||
} else {
|
||||
activeParent
|
||||
? node.parentNode.removeAttribute('class')
|
||||
: node.removeAttribute('class');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* sidebar toggle
|
||||
*/
|
||||
function bindToggle (dom) {
|
||||
dom = typeof dom === 'object' ? dom : document.querySelector(dom);
|
||||
if (!dom) { return }
|
||||
var body = document.body;
|
||||
|
||||
dom.addEventListener('click', function () { return body.classList.toggle('close'); });
|
||||
|
||||
if (!/mobile/i.test(navigator.userAgent)) { return }
|
||||
document.querySelector('aside').addEventListener('click', function (event) {
|
||||
body.classList.toggle('close');
|
||||
});
|
||||
}
|
||||
|
||||
var OPTIONS$1 = {};
|
||||
var CACHE = {};
|
||||
|
||||
var renderTo = function (dom, content) {
|
||||
dom = typeof dom === 'object' ? dom : document.querySelector(dom);
|
||||
@@ -2399,12 +2418,16 @@ function renderArticle (content) {
|
||||
if (!renderNavbar.rendered) { renderNavbar(null, OPTIONS$1); }
|
||||
renderSidebar.rendered = false;
|
||||
renderNavbar.rendered = false;
|
||||
|
||||
if (OPTIONS$1.auto2top) { scroll2Top(); }
|
||||
}
|
||||
|
||||
/**
|
||||
* navbar
|
||||
*/
|
||||
function renderNavbar (content) {
|
||||
if (CACHE['navbar'] && CACHE['navbar'] === content) { return }
|
||||
CACHE['navbar'] = content;
|
||||
renderNavbar.rendered = true;
|
||||
|
||||
if (content) { renderTo('nav', marked(content)); }
|
||||
@@ -2415,8 +2438,6 @@ function renderNavbar (content) {
|
||||
* sidebar
|
||||
*/
|
||||
function renderSidebar (content) {
|
||||
renderSidebar.rendered = true;
|
||||
|
||||
var isToc = false;
|
||||
|
||||
if (content) {
|
||||
@@ -2428,11 +2449,49 @@ function renderSidebar (content) {
|
||||
isToc = true;
|
||||
}
|
||||
|
||||
renderSidebar.rendered = true;
|
||||
if (CACHE['sidebar'] && CACHE['sidebar'] === content) { return }
|
||||
CACHE['sidebar'] = content;
|
||||
renderTo('aside.sidebar', content);
|
||||
isToc ? scrollActiveSidebar() : activeLink('aside.sidebar', true);
|
||||
if (isToc) { scrollActiveSidebar(); }
|
||||
toc = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* render loading bar
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
function renderLoading (ref) {
|
||||
var loaded = ref.loaded;
|
||||
var total = ref.total;
|
||||
|
||||
var num = Math.floor(loaded / total * 100);
|
||||
|
||||
if (!CACHE['loading']) {
|
||||
var div = document.createElement('div');
|
||||
|
||||
div.classList.add('progress');
|
||||
document.body.appendChild(div);
|
||||
CACHE['loading'] = div;
|
||||
}
|
||||
|
||||
if (num >= 95) {
|
||||
clearTimeout(renderLoading.cacheTImeout);
|
||||
CACHE['loading'].style.width = '100%';
|
||||
renderLoading.cacheTImeout = setTimeout(function (_) {
|
||||
CACHE['loading'].style.opacity = 0;
|
||||
CACHE['loading'].style.width = '0%';
|
||||
}, 200);
|
||||
} else {
|
||||
CACHE['loading'].style.opacity = 1;
|
||||
CACHE['loading'].style.width = num + '%';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Config
|
||||
* @param {Object} options
|
||||
*/
|
||||
function config (options) {
|
||||
OPTIONS$1 = options;
|
||||
}
|
||||
@@ -2445,7 +2504,8 @@ var OPTIONS = {
|
||||
sidebarToggle: false,
|
||||
loadSidebar: null,
|
||||
loadNavbar: null,
|
||||
router: false
|
||||
router: false,
|
||||
auto2top: false
|
||||
};
|
||||
var script = document.currentScript || [].slice.call(document.getElementsByTagName('script')).pop();
|
||||
|
||||
@@ -2464,26 +2524,44 @@ if (script) {
|
||||
config(OPTIONS);
|
||||
|
||||
var cacheRoute = null;
|
||||
var cacheXhr = null;
|
||||
|
||||
var mainRender = function () {
|
||||
var mainRender = function (cb) {
|
||||
var route = getRoute();
|
||||
if (cacheRoute === route) { return }
|
||||
|
||||
if (cacheRoute === route) { return cb() }
|
||||
var wait;
|
||||
var basePath = cacheRoute = route;
|
||||
|
||||
if (!/\//.test(basePath)) {
|
||||
basePath = '';
|
||||
} else if (basePath && !/\/$/.test(basePath)) {
|
||||
basePath = basePath.match(/(\S+\/)[^\/]+$/)[1];
|
||||
basePath = basePath.match(/(\S*\/)[^\/]+$/)[1];
|
||||
}
|
||||
|
||||
cacheXhr && cacheXhr.abort && cacheXhr.abort();
|
||||
// Render markdown file
|
||||
load((!route || /\/$/.test(route)) ? (route + "README.md") : (route + ".md"))
|
||||
.then(renderArticle, function (_) { return renderArticle(null); });
|
||||
cacheXhr = load(
|
||||
(!route || /\/$/.test(route)) ? (route + "README.md") : (route + ".md"),
|
||||
'GET',
|
||||
renderLoading);
|
||||
|
||||
cacheXhr.then(function (result) {
|
||||
renderArticle(result);
|
||||
if (OPTIONS.loadSidebar) {
|
||||
if (wait === false) { cb(); }
|
||||
wait = false;
|
||||
} else {
|
||||
cb();
|
||||
}
|
||||
}, function (_) { return renderArticle(null); });
|
||||
|
||||
// Render sidebar
|
||||
if (OPTIONS.loadSidebar) {
|
||||
load(basePath + OPTIONS.loadSidebar).then(renderSidebar);
|
||||
load(basePath + OPTIONS.loadSidebar).then(function (result) {
|
||||
renderSidebar(result);
|
||||
if (wait === false) { cb(); }
|
||||
wait = false;
|
||||
});
|
||||
}
|
||||
|
||||
// Render navbar
|
||||
@@ -2495,13 +2573,19 @@ var mainRender = function () {
|
||||
var Docsify = function () {
|
||||
var dom = document.querySelector(OPTIONS.el) || document.body;
|
||||
var replace = dom !== document.body;
|
||||
var main = function () {
|
||||
mainRender(function (_) {
|
||||
activeLink('aside.sidebar', true);
|
||||
scrollIntoView();
|
||||
});
|
||||
};
|
||||
|
||||
// Render app
|
||||
renderApp(dom, replace);
|
||||
mainRender();
|
||||
main();
|
||||
if (OPTIONS.router) {
|
||||
if (!/^#\//.test(window.location.hash)) { window.location.hash = '#/'; }
|
||||
window.addEventListener('hashchange', mainRender);
|
||||
window.addEventListener('hashchange', main);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Vendored
+2
-2
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "docsify",
|
||||
"version": "1.0.1",
|
||||
"version": "1.1.2",
|
||||
"description": "A magical documentation generator.",
|
||||
"main": "lib/docsify.js",
|
||||
"files": [
|
||||
|
||||
+20
-11
@@ -1,10 +1,11 @@
|
||||
import { isMobile } from './util'
|
||||
|
||||
/**
|
||||
* Active sidebar when scroll
|
||||
* @link https://buble.surge.sh/
|
||||
*/
|
||||
export function scrollActiveSidebar () {
|
||||
if (/mobile/i.test(navigator.userAgent)) return
|
||||
if (isMobile()) return
|
||||
|
||||
const anchors = document.querySelectorAll('.anchor')
|
||||
const nav = {}
|
||||
@@ -39,19 +40,18 @@ export function scrollActiveSidebar () {
|
||||
}
|
||||
}
|
||||
|
||||
document.querySelector('main .content').addEventListener('scroll', highlight)
|
||||
const dom = document.querySelector('main .content')
|
||||
dom.removeEventListener('scroll', highlight)
|
||||
dom.addEventListener('scroll', highlight)
|
||||
highlight()
|
||||
}
|
||||
|
||||
function scrollIntoView () {
|
||||
const id = window.location.hash.match(/#[^#\/]+$/g)
|
||||
if (!id || !id.length) return
|
||||
const section = document.querySelector(id[0])
|
||||
export function scrollIntoView () {
|
||||
const id = window.location.hash.match(/#[^#\/]+$/g)
|
||||
if (!id || !id.length) return
|
||||
const section = document.querySelector(id[0])
|
||||
|
||||
if (section) section.scrollIntoView()
|
||||
}
|
||||
|
||||
window.addEventListener('hashchange', scrollIntoView)
|
||||
scrollIntoView()
|
||||
if (section) section.scrollIntoView()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,3 +91,12 @@ export function bindToggle (dom) {
|
||||
body.classList.toggle('close')
|
||||
})
|
||||
}
|
||||
|
||||
let cacheContentDOM
|
||||
export function scroll2Top () {
|
||||
if (!cacheContentDOM) {
|
||||
const dom = isMobile() ? 'body' : 'section.content'
|
||||
cacheContentDOM = document.querySelector(dom)
|
||||
}
|
||||
cacheContentDOM.scrollTop = 0
|
||||
}
|
||||
|
||||
+36
-10
@@ -1,4 +1,5 @@
|
||||
import { load, camel2kebab, isNil, getRoute } from './util'
|
||||
import { activeLink, scrollIntoView } from './event'
|
||||
import * as render from './render'
|
||||
|
||||
const OPTIONS = {
|
||||
@@ -9,7 +10,8 @@ const OPTIONS = {
|
||||
sidebarToggle: false,
|
||||
loadSidebar: null,
|
||||
loadNavbar: null,
|
||||
router: false
|
||||
router: false,
|
||||
auto2top: false
|
||||
}
|
||||
const script = document.currentScript || [].slice.call(document.getElementsByTagName('script')).pop()
|
||||
|
||||
@@ -28,26 +30,44 @@ if (script) {
|
||||
render.config(OPTIONS)
|
||||
|
||||
let cacheRoute = null
|
||||
let cacheXhr = null
|
||||
|
||||
const mainRender = function () {
|
||||
const mainRender = function (cb) {
|
||||
const route = getRoute()
|
||||
if (cacheRoute === route) return
|
||||
|
||||
if (cacheRoute === route) return cb()
|
||||
let wait
|
||||
let basePath = cacheRoute = route
|
||||
|
||||
if (!/\//.test(basePath)) {
|
||||
basePath = ''
|
||||
} else if (basePath && !/\/$/.test(basePath)) {
|
||||
basePath = basePath.match(/(\S+\/)[^\/]+$/)[1]
|
||||
basePath = basePath.match(/(\S*\/)[^\/]+$/)[1]
|
||||
}
|
||||
|
||||
cacheXhr && cacheXhr.abort && cacheXhr.abort()
|
||||
// Render markdown file
|
||||
load((!route || /\/$/.test(route)) ? `${route}README.md` : `${route}.md`)
|
||||
.then(render.renderArticle, _ => render.renderArticle(null))
|
||||
cacheXhr = load(
|
||||
(!route || /\/$/.test(route)) ? `${route}README.md` : `${route}.md`,
|
||||
'GET',
|
||||
render.renderLoading)
|
||||
|
||||
cacheXhr.then(result => {
|
||||
render.renderArticle(result)
|
||||
if (OPTIONS.loadSidebar) {
|
||||
if (wait === false) cb()
|
||||
wait = false
|
||||
} else {
|
||||
cb()
|
||||
}
|
||||
}, _ => render.renderArticle(null))
|
||||
|
||||
// Render sidebar
|
||||
if (OPTIONS.loadSidebar) {
|
||||
load(basePath + OPTIONS.loadSidebar).then(render.renderSidebar)
|
||||
load(basePath + OPTIONS.loadSidebar).then(result => {
|
||||
render.renderSidebar(result)
|
||||
if (wait === false) cb()
|
||||
wait = false
|
||||
})
|
||||
}
|
||||
|
||||
// Render navbar
|
||||
@@ -59,13 +79,19 @@ const mainRender = function () {
|
||||
const Docsify = function () {
|
||||
const dom = document.querySelector(OPTIONS.el) || document.body
|
||||
const replace = dom !== document.body
|
||||
const main = function () {
|
||||
mainRender(_ => {
|
||||
activeLink('aside.sidebar', true)
|
||||
scrollIntoView()
|
||||
})
|
||||
}
|
||||
|
||||
// Render app
|
||||
render.renderApp(dom, replace)
|
||||
mainRender()
|
||||
main()
|
||||
if (OPTIONS.router) {
|
||||
if (!/^#\//.test(window.location.hash)) window.location.hash = '#/'
|
||||
window.addEventListener('hashchange', mainRender)
|
||||
window.addEventListener('hashchange', main)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+43
-4
@@ -1,10 +1,11 @@
|
||||
import marked from 'marked'
|
||||
import Prism from 'prismjs'
|
||||
import * as tpl from './tpl'
|
||||
import { activeLink, scrollActiveSidebar, bindToggle } from './event'
|
||||
import { activeLink, scrollActiveSidebar, bindToggle, scroll2Top } from './event'
|
||||
import { genTree, getRoute } from './util'
|
||||
|
||||
let OPTIONS = {}
|
||||
const CACHE = {}
|
||||
|
||||
const renderTo = function (dom, content) {
|
||||
dom = typeof dom === 'object' ? dom : document.querySelector(dom)
|
||||
@@ -68,12 +69,16 @@ export function renderArticle (content) {
|
||||
if (!renderNavbar.rendered) renderNavbar(null, OPTIONS)
|
||||
renderSidebar.rendered = false
|
||||
renderNavbar.rendered = false
|
||||
|
||||
if (OPTIONS.auto2top) scroll2Top()
|
||||
}
|
||||
|
||||
/**
|
||||
* navbar
|
||||
*/
|
||||
export function renderNavbar (content) {
|
||||
if (CACHE['navbar'] && CACHE['navbar'] === content) return
|
||||
CACHE['navbar'] = content
|
||||
renderNavbar.rendered = true
|
||||
|
||||
if (content) renderTo('nav', marked(content))
|
||||
@@ -84,8 +89,6 @@ export function renderNavbar (content) {
|
||||
* sidebar
|
||||
*/
|
||||
export function renderSidebar (content) {
|
||||
renderSidebar.rendered = true
|
||||
|
||||
let isToc = false
|
||||
|
||||
if (content) {
|
||||
@@ -97,11 +100,47 @@ export function renderSidebar (content) {
|
||||
isToc = true
|
||||
}
|
||||
|
||||
renderSidebar.rendered = true
|
||||
if (CACHE['sidebar'] && CACHE['sidebar'] === content) return
|
||||
CACHE['sidebar'] = content
|
||||
renderTo('aside.sidebar', content)
|
||||
isToc ? scrollActiveSidebar() : activeLink('aside.sidebar', true)
|
||||
if (isToc) scrollActiveSidebar()
|
||||
toc = []
|
||||
}
|
||||
|
||||
/**
|
||||
* render loading bar
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
export function renderLoading ({ loaded, total }) {
|
||||
const num = Math.floor(loaded / total * 100)
|
||||
|
||||
if (!CACHE['loading']) {
|
||||
const div = document.createElement('div')
|
||||
|
||||
div.classList.add('progress')
|
||||
document.body.appendChild(div)
|
||||
CACHE['loading'] = div
|
||||
}
|
||||
|
||||
if (num >= 95) {
|
||||
clearTimeout(renderLoading.cacheTImeout)
|
||||
CACHE['loading'].style.width = '100%'
|
||||
renderLoading.cacheTImeout = setTimeout(_ => {
|
||||
CACHE['loading'].style.opacity = 0
|
||||
CACHE['loading'].style.width = '0%'
|
||||
}, 200)
|
||||
} else {
|
||||
CACHE['loading'].style.opacity = 1
|
||||
CACHE['loading'].style.width = num + '%'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Config
|
||||
* @param {Object} options
|
||||
*/
|
||||
export function config (options) {
|
||||
OPTIONS = options
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,18 @@
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
.progress {
|
||||
background-color: $color-primary;
|
||||
height: 2px;
|
||||
left: 0px;
|
||||
position: fixed;
|
||||
right: 0px;
|
||||
top: 0px;
|
||||
transition: width 0.2s, opacity 0.4s;
|
||||
width: 0%;
|
||||
z-index: 999999;
|
||||
}
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ body {
|
||||
|
||||
ul li.active>a {
|
||||
color: $color-primary;
|
||||
font-weight: 500;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,3 +57,4 @@ export function tree (toc, tpl = '') {
|
||||
|
||||
return tpl
|
||||
}
|
||||
|
||||
|
||||
+14
-3
@@ -1,10 +1,11 @@
|
||||
/**
|
||||
* Simple ajax
|
||||
* @param {String} url
|
||||
* @param {String} [method=get]
|
||||
* @param {String} [method=GET]
|
||||
* @param {Function} [loading] handle loading
|
||||
* @return {Promise}
|
||||
*/
|
||||
export function load (url, method = 'get') {
|
||||
export function load (url, method = 'GET', loading) {
|
||||
const xhr = new XMLHttpRequest()
|
||||
|
||||
xhr.open(method, url)
|
||||
@@ -12,11 +13,16 @@ export function load (url, method = 'get') {
|
||||
|
||||
return {
|
||||
then: function (success, error = function () {}) {
|
||||
if (loading) {
|
||||
xhr.addEventListener('progress', loading)
|
||||
xhr.addEventListener('loaded', loading)
|
||||
}
|
||||
xhr.addEventListener('error', error)
|
||||
xhr.addEventListener('load', ({ target }) => {
|
||||
target.status >= 400 ? error(target) : success(target.response)
|
||||
})
|
||||
}
|
||||
},
|
||||
abort: () => xhr.readyState !== 4 && xhr.abort()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,3 +95,8 @@ export function getRoute () {
|
||||
|
||||
return route
|
||||
}
|
||||
|
||||
export function isMobile () {
|
||||
return /mobile/i.test(navigator.userAgent)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user