refactor: partial code refactoring && optimization TOC

This commit is contained in:
XPoet 2020-10-21 19:36:38 +08:00
parent 72bb6ac530
commit b3a397f7dd
16 changed files with 408 additions and 364 deletions

View File

@ -86,7 +86,7 @@ website_count:
# See: https://github.com/theme-next/hexo-generator-searchdb
# ---------------------------------------------------------------------------------------
local_search:
enable: true
enable: false
# If auto, trigger search by changing input.
# If manual, trigger search by pressing enter key or search button.
@ -141,7 +141,7 @@ side_tools:
# Back to top
# ---------------------------------------------------------------------------------------
back2top:
enable: false
enable: true
# ---------------------------------------------------------------------------------------

View File

@ -15,10 +15,14 @@
title = __('tag') + ': ' + page.tag;
} else if (page.title === 'about') {
title = __('about');
} else if (page.title === 'links') {
title = __('links');
}
%>
<title>
<% if (title){ %><%= title %> | <% } %><%= config.title %>
<% if (title){ %><%= title %> |
<% } %>
<%= config.title %>
</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<% if (theme.style.favicon){ %>

View File

@ -1,21 +1,24 @@
<%- js([
'js/main.js',
'js/utils.js',
'js/header-shrink.js',
'js/toggle-mode.js'
'js/dark-light-toggle.js',
'js/main.js'
]) %>
<% if (theme.back2top.enable) { %>
<%- js('js/scroll-to-top.js') %>
<%- js('js/back2top.js') %>
<% } %>
<% if (is_post()) { %>
<%- js('js/left-side-toggle.js') %>
<% if (theme.code_copy.enable) { %>
<%- js('js/code-copy.js') %>
<% } %>
<% if (theme.toc.enable) { %>
<%- js(['lib/anime.min.js', 'js/toc.js', 'js/post-toc.js']) %>
<%- js(['lib/anime.min.js', 'js/toc.js']) %>
<% } %>
<% } %>

View File

@ -8,18 +8,21 @@ const url = require('url');
* Export theme config to js
*/
hexo.extend.helper.register('export_config', function () {
let {config, theme} = this;
let exportConfig = {
hostname: url.parse(config.url).hostname || config.url,
root: config.root,
localsearch: theme.local_search,
themeInfo: theme.theme_info,
codeblock: theme.codeblock
};
if (config.search) {
exportConfig.path = config.search.path;
}
return `<script id="hexo-configurations">
let {config, theme} = this;
let exportConfig = {
hostname: url.parse(config.url).hostname || config.url,
root: config.root,
localsearch: theme.local_search,
themeInfo: theme.theme_info,
codeblock: theme.codeblock,
toc: theme.toc,
back2top: theme.back2top
};
if (config.search) {
exportConfig.path = config.search.path;
}
return `<script id="hexo-configurations">
let ILS = window.ILS || {};
let CONFIG = ${JSON.stringify(exportConfig)};
</script>`;
});

View File

@ -69,15 +69,14 @@
h1, h2, h3, h4, h5, h6 {
// TODO: ...
}
h1 {
color: var(--second-text-color);
font-size: 2em;
font-weight: 600;
margin-block-start: 1.1em;
margin-block-end: 1.1em;
margin-block-start: 1.4em;
margin-block-end: 1.0em;
}
@ -85,16 +84,16 @@
color: var(--second-text-color);
font-size: 1.8em;
font-weight: 600;
margin-block-start: 1.1em;
margin-block-end: 1.1em;
margin-block-start: 1.4em;
margin-block-end: 1.0em;
}
h3 {
color: var(--second-text-color);
font-size: 1.6em;
font-weight: 550;
margin-block-start: 1em;
margin-block-end: 1em;
margin-block-start: 1.2em;
margin-block-end: 0.8em;
}
@ -102,16 +101,16 @@
color: var(--second-text-color);
font-size: 1.4em;
font-weight: 550;
margin-block-start: 1em;
margin-block-end: 1em;
margin-block-start: 1.2em;
margin-block-end: 0.8em;
}
h5 {
color: var(--second-text-color);
font-size: 1.2em;
font-weight: 500;
margin-block-start: 0.9em;
margin-block-end: 0.9em;
margin-block-start: 1.0em;
margin-block-end: 0.6em;
}
@ -119,8 +118,8 @@
color: var(--second-text-color);
font-size: 1.2em;
font-weight: 500;
margin-block-start: 0.9em;
margin-block-end: 0.9em;
margin-block-start: 1.0em;
margin-block-end: 0.6em;
}

35
source/js/back2top.js Normal file
View File

@ -0,0 +1,35 @@
window.addEventListener('DOMContentLoaded', () => {
ILS.utils = {
...ILS.utils,
back2TopButton_dom: document.querySelector('.scroll-to-top'),
back2top() {
const scrollTopTimer = setInterval(function () {
let top = document.body.scrollTop || document.documentElement.scrollTop;
let speed = top / 2;
if (document.body.scrollTop !== 0) {
document.body.scrollTop -= speed;
} else {
document.documentElement.scrollTop -= speed;
}
if (top === 0) {
clearInterval(scrollTopTimer);
}
}, 30);
},
initBack2TopButton() {
if (ILS.utils.back2TopButton_dom) {
ILS.utils.back2TopButton_dom.addEventListener('click', () => {
this.back2top();
});
}
},
}
ILS.utils.initBack2TopButton();
});

View File

@ -1,45 +1,45 @@
HTMLElement.prototype.wrap = function (wrapper) {
this.parentNode.insertBefore(wrapper, this);
this.parentNode.removeChild(this);
wrapper.appendChild(this);
this.parentNode.insertBefore(wrapper, this);
this.parentNode.removeChild(this);
wrapper.appendChild(this);
};
window.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('figure.highlight').forEach(element => {
const box = document.createElement('div');
element.wrap(box);
box.classList.add('highlight-container');
box.insertAdjacentHTML('beforeend', '<div class="copy-btn"><i class="fa fa-clipboard"></i></div>');
var button = element.parentNode.querySelector('.copy-btn');
button.addEventListener('click', event => {
var target = event.currentTarget;
var code = [...target.parentNode.querySelectorAll('.code .line')].map(line => line.innerText).join('\n');
var ta = document.createElement('textarea');
ta.style.top = window.scrollY + 'px'; // Prevent page scrolling
ta.style.position = 'absolute';
ta.style.opacity = '0';
ta.readOnly = true;
ta.value = code;
document.body.append(ta);
const selection = document.getSelection();
const selected = selection.rangeCount > 0 ? selection.getRangeAt(0) : false;
ta.select();
ta.setSelectionRange(0, code.length);
ta.readOnly = false;
var result = document.execCommand('copy');
target.querySelector('i').className = result ? 'fa fa-check' : 'fa fa-times';
ta.blur(); // For iOS
target.blur();
if (selected) {
selection.removeAllRanges();
selection.addRange(selected);
}
document.body.removeChild(ta);
});
button.addEventListener('mouseleave', event => {
setTimeout(() => {
event.target.querySelector('i').className = 'fa fa-clipboard';
}, 300);
});
document.querySelectorAll('figure.highlight').forEach(element => {
const box = document.createElement('div');
element.wrap(box);
box.classList.add('highlight-container');
box.insertAdjacentHTML('beforeend', '<div class="copy-btn"><i class="fa fa-clipboard"></i></div>');
var button = element.parentNode.querySelector('.copy-btn');
button.addEventListener('click', event => {
var target = event.currentTarget;
var code = [...target.parentNode.querySelectorAll('.code .line')].map(line => line.innerText).join('\n');
var ta = document.createElement('textarea');
ta.style.top = window.scrollY + 'px'; // Prevent page scrolling
ta.style.position = 'absolute';
ta.style.opacity = '0';
ta.readOnly = true;
ta.value = code;
document.body.append(ta);
const selection = document.getSelection();
const selected = selection.rangeCount > 0 ? selection.getRangeAt(0) : false;
ta.select();
ta.setSelectionRange(0, code.length);
ta.readOnly = false;
var result = document.execCommand('copy');
target.querySelector('i').className = result ? 'fa fa-check' : 'fa fa-times';
ta.blur(); // For iOS
target.blur();
if (selected) {
selection.removeAllRanges();
selection.addRange(selected);
}
document.body.removeChild(ta);
});
button.addEventListener('mouseleave', event => {
setTimeout(() => {
event.target.querySelector('i').className = 'fa fa-clipboard';
}, 300);
});
});
});

View File

@ -0,0 +1,72 @@
window.addEventListener('DOMContentLoaded', () => {
ILS.utils.modeToggle = {
localStorageKey: 'MAGIC',
modeToggleButton_dom: document.querySelector('.mode-toggle'),
iconDom: document.querySelector('.mode-toggle i'),
articleContent: document.querySelector('.main-content'),
setItemUtil(modeClass, prefersColorScheme) {
document.body.classList.toggle(modeClass);
const isDark = document.body.className.indexOf(modeClass) === -1;
if (isDark) {
this.iconDom.className = 'fa fa-moon-o';
this.articleContent.classList.remove('night-code-theme');
} else {
this.iconDom.className = 'fa fa-lightbulb-o';
this.articleContent.classList.add('night-code-theme');
}
localStorage.setItem(this.localStorageKey, JSON.stringify(
{
prefersColorScheme: prefersColorScheme,
isDark: isDark
}
));
},
initModeStatus() {
this.modeConfig = JSON.parse(localStorage.getItem(this.localStorageKey));
if (this.modeConfig) {
if (this.modeConfig.prefersColorScheme === 'dark') {
if (this.modeConfig.isDark) {
document.body.classList.remove('light-mode');
this.articleContent.classList.remove('night-code-theme');
this.iconDom.className = 'fa fa-lightbulb-o';
} else {
document.body.classList.add('light-mode');
this.articleContent.classList.add('night-code-theme');
this.iconDom.className = 'fa fa-moon-o';
}
} else {
if (this.modeConfig.isDark) {
document.body.classList.remove('dark-mode');
this.articleContent.classList.remove('night-code-theme');
this.iconDom.className = 'fa fa-moon-o';
} else {
document.body.classList.add('dark-mode');
this.articleContent.classList.add('night-code-theme');
this.iconDom.className = 'fa fa-lightbulb-o';
}
}
}
},
initModeToggleButton() {
this.modeToggleButton_dom.addEventListener('click', () => {
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
this.setItemUtil('light-mode', 'dark');
} else {
this.setItemUtil('dark-mode', 'light');
}
});
}
}
ILS.utils.modeToggle.initModeStatus();
ILS.utils.modeToggle.initModeToggleButton();
});

View File

@ -1,36 +1,50 @@
const pageTemplateDom = document.querySelector('.page-main-content');
const sidebarToolsDom = document.querySelector('.sidebar-tools');
const headerDom = document.querySelector('.header-wrapper');
const menuBarDom = document.querySelector('.menu-bar');
const windowMaskDom = document.querySelector('.window-mask');
window.addEventListener('DOMContentLoaded', () => {
ILS.utils.headerShrink = {
pageTemplateDom: document.querySelector('.page-main-content'),
sidebarToolsDom: document.querySelector('.sidebar-tools'),
headerDom: document.querySelector('.header-wrapper'),
menuBarDom: document.querySelector('.menu-bar'),
windowMaskDom: document.querySelector('.window-mask'),
let isHeaderShrink = false;
const headerHeight = headerDom.getBoundingClientRect().height;
isHeaderShrink: false,
window.addEventListener('scroll', function (_e) {
const scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
if (!isHeaderShrink && scrollTop > headerHeight) {
isHeaderShrink = true;
headerDom.classList.add('header-wrapper-shrink');
pageTemplateDom.classList.add('page-main-content-top-shrink');
sidebarToolsDom.classList.add('sidebar-tools-shrink');
init() {
this.headerHeight = this.headerDom.getBoundingClientRect().height;
},
} else if (isHeaderShrink && scrollTop <= headerHeight) {
isHeaderShrink = false;
headerDom.classList.remove('header-wrapper-shrink');
pageTemplateDom.classList.remove('page-main-content-top-shrink');
sidebarToolsDom.classList.remove('sidebar-tools-shrink');
headerShrink() {
const scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
if (!this.isHeaderShrink && scrollTop > this.headerHeight) {
this.isHeaderShrink = true;
this.headerDom.classList.add('header-wrapper-shrink');
this.pageTemplateDom.classList.add('page-main-content-top-shrink');
this.sidebarToolsDom.classList.add('sidebar-tools-shrink');
} else if (this.isHeaderShrink && scrollTop <= this.headerHeight) {
this.isHeaderShrink = false;
this.headerDom.classList.remove('header-wrapper-shrink');
this.pageTemplateDom.classList.remove('page-main-content-top-shrink');
this.sidebarToolsDom.classList.remove('sidebar-tools-shrink');
}
},
initMenuBarButton() {
this.menuBarDom.addEventListener('click', () => {
this.headerDom.classList.toggle('header-drawer-show');
});
},
initWindowMask() {
this.windowMaskDom.addEventListener('click', () => {
this.headerDom.classList.toggle('header-drawer-show');
});
},
}
ILS.utils.headerShrink.init();
ILS.utils.headerShrink.initMenuBarButton();
ILS.utils.headerShrink.initWindowMask();
});
menuBarDom.addEventListener('click', function (_e) {
headerDom.classList.toggle('header-drawer-show');
});
windowMaskDom.addEventListener('click', function (_e) {
headerDom.classList.toggle('header-drawer-show');
});

View File

@ -0,0 +1,38 @@
window.addEventListener('DOMContentLoaded', () => {
ILS.utils.leftSideToggle = {
init() {
this.toggleBar = document.querySelector('.page-aside-toggle');
this.pageTopDom = document.querySelector('.page-main-content-top');
this.containerDom = document.querySelector('.page-container');
this.leftAsideDom = document.querySelector('.page-aside');
this.headerContentDom = document.querySelector('.header-wrapper .header-content');
this.mainContentDom = document.querySelector('.page-main-content-middle .main-content');
this.isOpenPageAside = false;
},
initToggleBarButton() {
if (this.toggleBar) {
this.toggleBar.addEventListener('click', () => {
this.isOpenPageAside = !this.isOpenPageAside;
this.changePageLayoutWhenOpenToggle(this.isOpenPageAside);
})
}
},
changePageLayoutWhenOpenToggle(isOpen) {
const pageAsideWidth = '258px';
this.containerDom.style.paddingLeft = isOpen ? pageAsideWidth : '0';
this.pageTopDom.style.paddingLeft = isOpen ? pageAsideWidth : '0';
this.pageTopDom.style.paddingLeft = isOpen ? pageAsideWidth : '0';
this.leftAsideDom.style.left = isOpen ? '0' : `-${pageAsideWidth}`;
this.headerContentDom.style.width = isOpen ? '76%' : '62%';
this.mainContentDom.style.width = isOpen ? '76%' : '62%';
},
}
ILS.utils.leftSideToggle.init();
ILS.utils.leftSideToggle.initToggleBarButton();
});

View File

@ -1,47 +1,8 @@
window.addEventListener('DOMContentLoaded', () => {
console.log(`${CONFIG.themeInfo.name} v${CONFIG.themeInfo.version}`);
// print theme info
ILS.utils.printThemeInfo();
pageAsideOpenToggle();
// init scroll
ILS.utils.initWindowScroll();
});
const pageAsideOpenToggle = () => {
const toggleDom = document.querySelector('.page-aside-toggle');
const pageTopDom = document.querySelector('.page-main-content-top');
const containerDom = document.querySelector('.page-container');
const leftAsideDom = document.querySelector('.page-aside');
const headerContentDom = document.querySelector('.header-wrapper .header-content');
const mainContentDom = document.querySelector('.page-main-content-middle .main-content');
let isOpen = false;
const openToggle = (isOpen) => {
const pageAsideWidth = '258px';
containerDom.style.paddingLeft = isOpen ? pageAsideWidth : '0';
pageTopDom.style.paddingLeft = isOpen ? pageAsideWidth : '0';
pageTopDom.style.paddingLeft = isOpen ? pageAsideWidth : '0';
leftAsideDom.style.left = isOpen ? '0' : `-${pageAsideWidth}`;
headerContentDom.style.width = isOpen ? '76%' : '62%';
mainContentDom.style.width = isOpen ? '76%' : '62%';
}
toggleDom.addEventListener('click', () => {
isOpen = !isOpen;
openToggle(isOpen);
})
window.utils = {
openToggle: () => {
isOpen = true;
openToggle(isOpen);
}
}
}

View File

@ -1,10 +0,0 @@
window.addEventListener('DOMContentLoaded', () => {
const navItems = document.querySelectorAll('.post-toc-wrap .post-toc li');
const toggleDom = document.querySelector('.page-aside-toggle');
if (navItems.length) {
toggleDom.style.display = 'flex';
window.utils.openToggle();
}
});

View File

@ -1,53 +0,0 @@
(function () {
const scrollToTopDom = document.querySelector('.scroll-to-top');
const headerProgressDom = document.querySelector('.header-progress');
const headerWrapper = document.querySelector('.header-wrapper');
const backToTop = () => {
let scrollTopTimer = setInterval(function () {
let top = document.body.scrollTop || document.documentElement.scrollTop;
let speed = top / 2;
if (document.body.scrollTop !== 0) {
document.body.scrollTop -= speed;
} else {
document.documentElement.scrollTop -= speed;
}
if (top === 0) {
clearInterval(scrollTopTimer);
}
}, 30);
};
scrollToTopDom.addEventListener('click', () => {
backToTop();
});
let prevScroll = 0;
window.addEventListener('scroll', function (_e) {
// back to top & show scroll percent
const scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
const scrollHeight = document.body.scrollHeight || document.documentElement.scrollHeight;
const clientHeight = window.innerHeight || document.documentElement.clientHeight;
const percent = Math.round(scrollTop / (scrollHeight - clientHeight) * 100).toFixed(0);
const ProgressPercent = (scrollTop / (scrollHeight - clientHeight) * 100).toFixed(3);
if (percent === '0') {
scrollToTopDom.style.display = 'none';
headerProgressDom.style.display = 'none';
} else {
scrollToTopDom.style.display = 'flex';
headerProgressDom.style.display = 'block';
headerProgressDom.style.width = `${ProgressPercent}%`;
}
// hide header handle
const opacity = headerWrapper.style.opacity
if (scrollTop > prevScroll && scrollTop > 360) {
if (opacity > 0) headerWrapper.style.opacity = '0';
} else {
if (opacity < 1) headerWrapper.style.opacity = '1';
}
prevScroll = scrollTop
});
})();

View File

@ -1,107 +1,95 @@
window.addEventListener('DOMContentLoaded', () => {
const articleToc = document.querySelector('.article-toc');
const postTocWrap = document.querySelector('.post-toc-wrap');
const navItems = postTocWrap.querySelectorAll('.post-toc li');
const headerWrapper = document.querySelector('.header-wrapper');
ILS.utils.navItems = document.querySelectorAll('.post-toc-wrap .post-toc li');
ILS.utils.articleToc_dom = document.querySelector('.article-toc');
ILS.utils.postTocWrap_dom = document.querySelector('.post-toc-wrap');
ILS.utils.headerWrapper_dom = document.querySelector('.header-wrapper');
if (navItems.length > 0) {
if (ILS.utils.navItems.length > 0) {
const sections = [...navItems].map(element => {
let link = element.querySelector('a.nav-link');
// TOC item animation navigate.
link.addEventListener('click', event => {
event.preventDefault();
let target = document.getElementById(event.currentTarget.getAttribute('href').replace('#', ''));
let offset = target.getBoundingClientRect().top + window.scrollY - 18;
window.anime({
targets: document.scrollingElement,
duration: 500,
easing: 'linear',
scrollTop: offset,
complete: function () {
setTimeout(() => {
if (headerWrapper.style.opacity !== '0') headerWrapper.style.opacity = '0'
}, 100)
}
ILS.utils = {
...ILS.utils,
findActiveIndexByTOC() {
if (!Array.isArray(ILS.utils.sections)) return;
let index = ILS.utils.sections.findIndex(element => {
return element && element.getBoundingClientRect().top - 20 > 0;
});
});
return document.getElementById(link.getAttribute('href').replace('#', ''));
});
function activateNavByIndex(target) {
if (target.classList.contains('active-current')) return;
document.querySelectorAll('.post-toc .active').forEach(element => {
element.classList.remove('active', 'active-current');
});
target.classList.add('active', 'active-current');
let parent = target.parentNode;
while (!parent.matches('.post-toc')) {
if (parent.matches('li')) parent.classList.add('active');
parent = parent.parentNode;
}
// Scrolling to center active TOC element if TOC content is taller then viewport.
window.anime({
targets: postTocWrap,
duration: 200,
easing: 'linear',
scrollTop: postTocWrap.scrollTop - (postTocWrap.offsetHeight / 2) + target.getBoundingClientRect().top - postTocWrap.getBoundingClientRect().top
});
}
function findIndex(entries) {
let index = 0;
let entry = entries[index];
if (entry.boundingClientRect.top > 0) {
index = sections.indexOf(entry.target);
return index === 0 ? 0 : index - 1;
}
for (; index < entries.length; index++) {
if (entries[index].boundingClientRect.top <= 0) {
entry = entries[index];
} else {
return sections.indexOf(entry.target);
if (index === -1) {
index = ILS.utils.sections.length - 1;
} else if (index > 0) {
index--;
}
}
return sections.indexOf(entry.target);
}
ILS.utils.activateNavByIndex(index);
},
function createIntersectionObserver(marginTop) {
registerSidebarTOC() {
ILS.utils.sections = [...document.querySelectorAll('.post-toc li a.nav-link')].map(element => {
const target = document.getElementById(decodeURI(element.getAttribute('href')).replace('#', ''));
element.addEventListener('click', event => {
event.preventDefault();
const offset = target.getBoundingClientRect().top + window.scrollY;
window.anime({
targets: document.scrollingElement,
duration: 500,
easing: 'linear',
scrollTop: offset - 10,
complete: function () {
setTimeout(() => {
if (ILS.utils.headerWrapper_dom.style.opacity !== '0') ILS.utils.headerWrapper_dom.style.opacity = '0'
}, 100)
}
});
});
return target;
});
},
marginTop = Math.floor(marginTop + 10000);
let intersectionObserver = new IntersectionObserver((entries, observe) => {
let scrollHeight = document.documentElement.scrollHeight + 100;
if (scrollHeight > marginTop) {
observe.disconnect();
createIntersectionObserver(scrollHeight);
return;
activateNavByIndex: function (index) {
const target = document.querySelectorAll('.post-toc li a.nav-link')[index];
if (!target || target.classList.contains('active-current')) return;
document.querySelectorAll('.post-toc .active').forEach(element => {
element.classList.remove('active', 'active-current');
});
target.classList.add('active', 'active-current');
let parent = target.parentNode;
while (!parent.matches('.post-toc')) {
if (parent.matches('li')) parent.classList.add('active');
parent = parent.parentNode;
}
let index = findIndex(entries);
activateNavByIndex(navItems[index]);
}, {
rootMargin: marginTop + 'px 0px -100% 0px',
threshold: 0
});
sections.forEach(element => {
element && intersectionObserver.observe(element);
});
// Scrolling to center active TOC element if TOC content is taller then viewport.
const tocElement = document.querySelector('.post-toc-wrap');
window.anime({
targets: tocElement,
duration: 200,
easing: 'linear',
scrollTop: tocElement.scrollTop - (tocElement.offsetHeight / 2) + target.getBoundingClientRect().top - tocElement.getBoundingClientRect().top
});
},
showPageAsideWhenHasTOC() {
ILS.utils.leftSideToggle.toggleBar.style.display = 'flex';
ILS.utils.leftSideToggle.isOpenPageAside = true;
ILS.utils.leftSideToggle.changePageLayoutWhenOpenToggle(ILS.utils.leftSideToggle.isOpenPageAside);
}
}
createIntersectionObserver(document.documentElement.scrollHeight);
ILS.utils.showPageAsideWhenHasTOC();
ILS.utils.registerSidebarTOC();
} else {
if (postTocWrap) {
postTocWrap.innerHTML = '';
postTocWrap.style.display = 'none';
if (ILS.utils.postTocWrap_dom) {
ILS.utils.postTocWrap_dom.innerHTML = '';
ILS.utils.postTocWrap_dom.style.display = 'none';
}
if (articleToc) {
articleToc.style.display = 'none';
if (ILS.utils.articleToc_dom) {
ILS.utils.articleToc_dom.style.display = 'none';
}
}
});

View File

@ -1,70 +0,0 @@
/**
* 日间/夜间 模式切换
*/
const localStorageKey = 'MAGIC'
const modeToggleBtn = document.querySelector('.mode-toggle');
const iconDom = modeToggleBtn.querySelector('i');
const articleContent = document.querySelector('.main-content');
const modeConfig = JSON.parse(localStorage.getItem(localStorageKey));
if (modeConfig) {
if (modeConfig.prefersColorScheme === 'dark') {
if (modeConfig.isDark) {
document.body.classList.remove('light-mode');
articleContent.classList.remove('night-code-theme');
iconDom.className = 'fa fa-lightbulb-o';
} else {
iconDom.className = 'fa fa-moon-o';
document.body.classList.add('light-mode');
articleContent.classList.add('night-code-theme');
}
} else {
if (modeConfig.isDark) {
document.body.classList.remove('dark-mode');
articleContent.classList.remove('night-code-theme');
iconDom.className = 'fa fa-moon-o';
} else {
document.body.classList.add('dark-mode');
iconDom.className = 'fa fa-lightbulb-o';
articleContent.classList.add('night-code-theme');
}
}
}
const setItemUtil = (modeClass, prefersColorScheme) => {
document.body.classList.toggle(modeClass);
const isDark = document.body.className.indexOf(modeClass) === -1;
if (isDark) {
iconDom.className = 'fa fa-moon-o';
articleContent.classList.remove('night-code-theme');
} else {
iconDom.className = 'fa fa-lightbulb-o';
articleContent.classList.add('night-code-theme');
}
localStorage.setItem(localStorageKey, JSON.stringify(
{
prefersColorScheme: prefersColorScheme,
isDark: isDark
}
));
};
modeToggleBtn.addEventListener('click', function (e) {
if (
window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
) {
setItemUtil('light-mode', 'dark');
} else {
setItemUtil('dark-mode', 'light');
}
});

60
source/js/utils.js Normal file
View File

@ -0,0 +1,60 @@
ILS.utils = {
printThemeInfo() {
console.log(`${CONFIG.themeInfo.name} v${CONFIG.themeInfo.version}`);
}
}
ILS.utils = {
...ILS.utils,
headerProgress_dom: document.querySelector('.header-progress'),
headerWrapper_dom: document.querySelector('.header-wrapper'),
// Scroll Style Handle
prevScrollValue: 0,
styleHandleWhenScroll() {
const scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
const scrollHeight = document.body.scrollHeight || document.documentElement.scrollHeight;
const clientHeight = window.innerHeight || document.documentElement.clientHeight;
const percent = Math.round(scrollTop / (scrollHeight - clientHeight) * 100).toFixed(0);
const ProgressPercent = (scrollTop / (scrollHeight - clientHeight) * 100).toFixed(3);
if (CONFIG.back2top.enable && ILS.utils.back2TopButton_dom) {
ILS.utils.back2TopButton_dom.style.display = percent === '0' ? 'none' : 'flex';
}
if (ILS.utils.headerProgress_dom) {
ILS.utils.headerProgress_dom.style.display = percent === '0' ? 'none' : 'block';
ILS.utils.headerProgress_dom.style.width = `${ProgressPercent}%`;
}
// hide header handle
const opacity = ILS.utils.headerWrapper_dom.style.opacity;
if (scrollTop > ILS.utils.prevScrollValue && scrollTop > 500) {
if (opacity !== '0') ILS.utils.headerWrapper_dom.style.opacity = '0';
} else {
if (opacity !== '1') ILS.utils.headerWrapper_dom.style.opacity = '1';
}
ILS.utils.prevScrollValue = scrollTop;
},
// 初始 window scroll 事件
initWindowScroll() {
window.addEventListener('scroll', function (_e) {
// style handle when scroll
ILS.utils.styleHandleWhenScroll();
// TOC scroll handle
if (CONFIG.toc.enable && ILS.utils.hasOwnProperty('findActiveIndexByTOC')) {
ILS.utils.findActiveIndexByTOC();
}
// header shrink
ILS.utils.headerShrink.headerShrink();
});
},
}