mirror of
https://github.com/dillonzq/LoveIt.git
synced 2025-03-13 19:27:47 +01:00
feature(header): add header config
This commit is contained in:
parent
d25cbf6cb6
commit
88576721cc
12 changed files with 142 additions and 81 deletions
|
@ -62,6 +62,7 @@
|
|||
|
||||
.page {
|
||||
max-width: 100%;
|
||||
padding-top: $page-padding-top-mobile;
|
||||
|
||||
.categories-card {
|
||||
.card-item {
|
||||
|
@ -80,8 +81,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dynamic-to-top {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
width: 100%;
|
||||
max-width: 980px;
|
||||
margin: 0 auto;
|
||||
padding-top: 6rem;
|
||||
padding-top: $page-padding-top-desktop;
|
||||
}
|
||||
|
||||
@import "_single";
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
header {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: $header-height;
|
||||
line-height: $header-height;
|
||||
z-index: 100;
|
||||
background-color: $header-background-color;
|
||||
|
||||
.dark-theme & {
|
||||
|
@ -12,7 +10,9 @@ header {
|
|||
|
||||
#header-desktop {
|
||||
display: block;
|
||||
z-index: 100;
|
||||
position: $header-position-desktop;
|
||||
height: $header-height-desktop;
|
||||
line-height: $header-height-desktop;
|
||||
|
||||
.header-wrapper {
|
||||
width: auto;
|
||||
|
@ -47,12 +47,14 @@ header {
|
|||
|
||||
#header-mobile {
|
||||
display: none;
|
||||
z-index: 100;
|
||||
transition: all 0.3s ease 0s;
|
||||
position: $header-position-mobile;
|
||||
height: $header-height-mobile;
|
||||
line-height: $header-height-mobile;
|
||||
|
||||
.header-wrapper {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
transition: all 0.3s ease 0s;
|
||||
|
||||
.header-container {
|
||||
display: flex;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
border-left: 1px solid $global-border-color;
|
||||
overflow-wrap: break-word;
|
||||
box-sizing: border-box;
|
||||
top: 12rem;
|
||||
top: $post-toc-top;
|
||||
|
||||
.dark-theme & {
|
||||
border-left: 1px solid $global-border-color-dark;
|
||||
|
|
|
@ -47,7 +47,8 @@ $selection-color-dark: rgba(38, 139, 211, 0.3) !default;
|
|||
|
||||
// ========== Header ========== //
|
||||
// Height of the header
|
||||
$header-height: 4rem !default;
|
||||
$header-height-desktop: 4rem !default;
|
||||
$header-height-mobile: 4rem !default;
|
||||
|
||||
// Color of the header background
|
||||
$header-background-color: #fafafa !default;
|
||||
|
|
|
@ -8,6 +8,24 @@
|
|||
$home-posts: false;
|
||||
{{- end -}}
|
||||
|
||||
{{- if eq .Site.Params.desktopHeaderMode "normal" -}}
|
||||
$header-position-desktop: static;
|
||||
$page-padding-top-desktop: 1rem;
|
||||
$post-toc-top: 7rem;
|
||||
{{- else -}}
|
||||
$header-position-desktop: fixed;
|
||||
$page-padding-top-desktop: 6rem;
|
||||
$post-toc-top: 12rem;
|
||||
{{- end -}}
|
||||
|
||||
{{- if eq .Site.Params.mobileHeaderMode "normal" -}}
|
||||
$header-position-mobile: static;
|
||||
$page-padding-top-mobile: 1rem;
|
||||
{{- else -}}
|
||||
$header-position-mobile: fixed;
|
||||
$page-padding-top-mobile: 6rem;
|
||||
{{- end -}}
|
||||
|
||||
@import "_variables";
|
||||
|
||||
{{- if fileExists "config/css/_custom.scss" -}}
|
||||
|
|
|
@ -1,14 +1,26 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
const forEachElement = (elements, handler) => {
|
||||
elements = elements || [];
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
handler(elements[i]);
|
||||
class Util {
|
||||
forEach(elements, handler) {
|
||||
elements = elements || [];
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
handler(elements[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
getScrollTop() {
|
||||
return (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
|
||||
}
|
||||
}
|
||||
|
||||
class Theme {
|
||||
constructor() {
|
||||
this.util = new Util();
|
||||
this.scrollTop = 0;
|
||||
this.scrollEvents = [];
|
||||
}
|
||||
|
||||
initMobileMenu() {
|
||||
document.getElementById('menu-toggle').onclick = () => {
|
||||
document.getElementById('menu-toggle').classList.toggle('active');
|
||||
|
@ -17,7 +29,7 @@
|
|||
}
|
||||
|
||||
initSwitchTheme() {
|
||||
forEachElement(document.getElementsByClassName('theme-switch'), (button) => {
|
||||
this.util.forEach(document.getElementsByClassName('theme-switch'), (button) => {
|
||||
button.onclick = () => {
|
||||
document.body.classList.toggle('dark-theme');
|
||||
window.isDark = !window.isDark;
|
||||
|
@ -27,55 +39,14 @@
|
|||
});
|
||||
}
|
||||
|
||||
initDynamicToTop() {
|
||||
const min = 300;
|
||||
const toTopButton = document.getElementById('dynamic-to-top');
|
||||
document.addEventListener('scroll', () => {
|
||||
const scrollTop = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
|
||||
if (typeof document.body.style.maxHeight === 'undefined') {
|
||||
toTopButton.style.position = 'absolute';
|
||||
toTopButton.style.top = scrollTop + window.document.documentElement.clientHeight - 20;
|
||||
}
|
||||
if (scrollTop > min) {
|
||||
(function fadeIn(el, display){
|
||||
display = display || 'block';
|
||||
if (el.style.display !== display) {
|
||||
el.style.opacity = 0;
|
||||
el.style.display = display;
|
||||
(function fade() {
|
||||
let val = parseFloat(el.style.opacity);
|
||||
if ((val += .1) <= 1) {
|
||||
el.style.opacity = val;
|
||||
requestAnimationFrame(fade);
|
||||
}
|
||||
})();
|
||||
}
|
||||
})(document.getElementById('dynamic-to-top'));
|
||||
} else {
|
||||
(function fadeOut(el){
|
||||
if (el.style.display !== 'none') {
|
||||
el.style.opacity = 1;
|
||||
(function fade() {
|
||||
if ((el.style.opacity -= .1) < 0) {
|
||||
el.style.display = 'none';
|
||||
} else {
|
||||
requestAnimationFrame(fade);
|
||||
}
|
||||
})();
|
||||
}
|
||||
})(document.getElementById('dynamic-to-top'));
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
initHighlight() {
|
||||
forEachElement(document.querySelectorAll('.highlight > .chroma'), (block) => {
|
||||
this.util.forEach(document.querySelectorAll('.highlight > .chroma'), (block) => {
|
||||
const codes = block.querySelectorAll('pre.chroma > code');
|
||||
const code = codes[codes.length - 1];
|
||||
const lang = code ? code.className.toLowerCase() : '';
|
||||
block.className += ' ' + lang;
|
||||
});
|
||||
forEachElement(document.querySelectorAll('.highlight > pre.chroma'), (block) => {
|
||||
this.util.forEach(document.querySelectorAll('.highlight > pre.chroma'), (block) => {
|
||||
const chroma = document.createElement('div');
|
||||
chroma.className = block.className;
|
||||
const table = document.createElement('table');
|
||||
|
@ -92,7 +63,7 @@
|
|||
}
|
||||
|
||||
initTable() {
|
||||
forEachElement(document.querySelectorAll('.content table'), (table) => {
|
||||
this.util.forEach(document.querySelectorAll('.content table'), (table) => {
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.className = 'table-wrapper';
|
||||
table.parentElement.replaceChild(wrapper, table);
|
||||
|
@ -102,7 +73,7 @@
|
|||
|
||||
initHeaderLink() {
|
||||
for (let num = 1; num <= 6; num++) {
|
||||
forEachElement(document.querySelectorAll('.content > h' + num), (header) => {
|
||||
this.util.forEach(document.querySelectorAll('.content > h' + num), (header) => {
|
||||
header.classList.add('headerLink');
|
||||
header.innerHTML = `<a href="#${header.id}"></a>${header.innerHTML}`;
|
||||
});
|
||||
|
@ -110,7 +81,7 @@
|
|||
}
|
||||
|
||||
_refactorToc(toc) {
|
||||
forEachElement(toc.querySelectorAll('a:first-child'), (link) => {
|
||||
this.util.forEach(toc.querySelectorAll('a:first-child'), (link) => {
|
||||
link.classList.add('toc-link');
|
||||
});
|
||||
|
||||
|
@ -127,19 +98,21 @@
|
|||
|
||||
_initTocState(tocContainer) {
|
||||
if (window.getComputedStyle(tocContainer, null).display !== 'none') {
|
||||
const TOP_SPACING = 80;
|
||||
const fixed = window.desktopHeaderMode !== 'normal';
|
||||
const fixedHeight = document.getElementById('header-desktop').getBoundingClientRect().height;
|
||||
const TOP_SPACING = 20 + (fixed ? fixedHeight : 0);
|
||||
const minTop = tocContainer.offsetTop;
|
||||
const minScrollTop = minTop - TOP_SPACING;
|
||||
const minScrollTop = minTop - TOP_SPACING + (fixed ? 0 : fixedHeight);
|
||||
const footerTop = document.getElementById('post-footer').offsetTop;
|
||||
const toclinks = tocContainer.getElementsByClassName('toc-link');
|
||||
const headerLinks = document.getElementsByClassName('headerLink') || [];
|
||||
const tocLinkLis = tocContainer.querySelectorAll('.post-toc-content li');
|
||||
const INDEX_SPACING = document.getElementById('header-desktop').getBoundingClientRect().height + 5;
|
||||
const INDEX_SPACING = 5 + (fixed ? fixedHeight : 0);
|
||||
|
||||
const changeTocState = () => {
|
||||
const scrollTop = document.documentElement.scrollTop;
|
||||
const scrollTop = this.util.getScrollTop();
|
||||
const maxTop = footerTop - tocContainer.getBoundingClientRect().height;
|
||||
const maxScrollTop = maxTop - TOP_SPACING;
|
||||
const maxScrollTop = maxTop - TOP_SPACING + (fixed ? 0 : fixedHeight);
|
||||
if (scrollTop < minScrollTop) {
|
||||
tocContainer.style.position = 'absolute';
|
||||
tocContainer.style.top = `${minTop}px`;
|
||||
|
@ -151,8 +124,8 @@
|
|||
tocContainer.style.top = `${TOP_SPACING}px`;
|
||||
}
|
||||
|
||||
forEachElement(toclinks, (link) => { link.classList.remove('active'); });
|
||||
forEachElement(tocLinkLis, (link) => { link.classList.remove('has-active'); });
|
||||
this.util.forEach(toclinks, (link) => { link.classList.remove('active'); });
|
||||
this.util.forEach(tocLinkLis, (link) => { link.classList.remove('has-active'); });
|
||||
let activeTocIndex = headerLinks.length - 1;
|
||||
for (let i = 0; i < headerLinks.length - 1; i++) {
|
||||
const thisTop = headerLinks[i].getBoundingClientRect().top;
|
||||
|
@ -175,7 +148,7 @@
|
|||
changeTocState();
|
||||
|
||||
if (!this._initTocOnce) {
|
||||
document.addEventListener('scroll', changeTocState, false);
|
||||
this.scrollEvents.push(changeTocState);
|
||||
this._initTocOnce = true;
|
||||
}
|
||||
}
|
||||
|
@ -190,7 +163,7 @@
|
|||
} else {
|
||||
this._refactorToc(toc);
|
||||
this._initTocState(tocContainer);
|
||||
window.addEventListener("resize", () => {
|
||||
window.addEventListener('resize', () => {
|
||||
window.setTimeout(() => {
|
||||
this._initTocState(tocContainer);
|
||||
}, 0);
|
||||
|
@ -258,14 +231,71 @@
|
|||
}
|
||||
}
|
||||
|
||||
initSmoothScroll() {
|
||||
new SmoothScroll('[href^="#"]', {speed: 300, speedAsDuration: true, header: '#header-desktop'});
|
||||
initScroll() {
|
||||
for (let i = 0; i < this.scrollEvents.length; i++) {
|
||||
document.addEventListener('scroll', this.scrollEvents[i], false);
|
||||
}
|
||||
const initSmoothScroll = () => {
|
||||
const isMobile = window.matchMedia('only screen and (max-width: 560px)').matches;
|
||||
if ((!isMobile && window.desktopHeaderMode === 'normal')
|
||||
|| (isMobile && window.mobileHeaderMode === 'normal')) {
|
||||
new SmoothScroll('[href^="#"]', {speed: 300, speedAsDuration: true});
|
||||
} else {
|
||||
new SmoothScroll('[href^="#"]', {speed: 300, speedAsDuration: true, header: '#header-desktop'});
|
||||
}
|
||||
};
|
||||
initSmoothScroll();
|
||||
window.addEventListener('resize', () => {
|
||||
window.setTimeout(() => {
|
||||
initSmoothScroll();
|
||||
}, 0);
|
||||
}, false);
|
||||
const headers = [];
|
||||
if (window.desktopHeaderMode === 'auto') headers.push(document.getElementById('header-desktop'));
|
||||
if (window.mobileHeaderMode === 'auto') headers.push(document.getElementById('header-mobile'));
|
||||
this.util.forEach(headers, (header) => {
|
||||
header.classList.add('animated');
|
||||
header.classList.add('faster');
|
||||
});
|
||||
const toTopButton = document.getElementById('dynamic-to-top');
|
||||
document.addEventListener('scroll', () => {
|
||||
const scrollTop = this.util.getScrollTop();
|
||||
this.util.forEach(headers, (header) => {
|
||||
if (this.scrollTop < scrollTop) {
|
||||
if (!header.classList.contains('fadeOutUp')) {
|
||||
header.classList.remove('fadeInDown');
|
||||
header.classList.add('fadeOutUp');
|
||||
}
|
||||
} else {
|
||||
if (!header.classList.contains('fadeInDown')) {
|
||||
header.classList.remove('fadeOutUp');
|
||||
header.classList.add('fadeInDown');
|
||||
}
|
||||
}
|
||||
if (scrollTop > 600) {
|
||||
if (this.scrollTop < scrollTop) {
|
||||
if (!toTopButton.classList.contains('fadeOut')) {
|
||||
toTopButton.classList.remove('fadeIn');
|
||||
toTopButton.classList.add('fadeOut');
|
||||
}
|
||||
} else {
|
||||
toTopButton.style.display = 'block';
|
||||
if (!toTopButton.classList.contains('fadeIn')) {
|
||||
toTopButton.classList.remove('fadeOut');
|
||||
toTopButton.classList.add('fadeIn');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
toTopButton.style.display = 'none';
|
||||
}
|
||||
});
|
||||
this.scrollTop = scrollTop;
|
||||
}, false);
|
||||
}
|
||||
|
||||
init() {
|
||||
this.initMobileMenu();
|
||||
this.initSwitchTheme();
|
||||
this.initDynamicToTop();
|
||||
this.initHighlight();
|
||||
this.initTable();
|
||||
this.initHeaderLink();
|
||||
|
@ -273,7 +303,7 @@
|
|||
this.initEcharts();
|
||||
this.initTypeit();
|
||||
this.initToc();
|
||||
this.initSmoothScroll();
|
||||
this.initScroll();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -285,6 +315,6 @@
|
|||
if (document.readyState !== 'loading') {
|
||||
themeInit();
|
||||
} else {
|
||||
document.addEventListener('DOMContentLoaded', themeInit);
|
||||
document.addEventListener('DOMContentLoaded', themeInit, false);
|
||||
}
|
||||
})();
|
||||
|
|
|
@ -112,6 +112,10 @@ dateFormatToUse = "2006-01-02"
|
|||
keywords = ["Theme", "Hugo"]
|
||||
# site default theme ("light", "dark", "auto")
|
||||
defaultTheme = "auto"
|
||||
# desktop header mode ("fixed", "normal", "auto")
|
||||
desktopHeaderMode = "fixed"
|
||||
# mobile header mode ("fixed", "normal", "auto")
|
||||
mobileHeaderMode = "auto"
|
||||
|
||||
# Home Page Info
|
||||
##home mode ("post", "other")
|
||||
|
|
|
@ -112,6 +112,10 @@ dateFormatToUse = "2006-01-02"
|
|||
keywords = ["Theme", "Hugo"]
|
||||
# 网站默认主题 ("light", "dark", "auto")
|
||||
defaultTheme = "auto"
|
||||
# 桌面端导航栏模式 ("fixed", "normal", "auto")
|
||||
desktopHeaderMode = "fixed"
|
||||
# 移动端导航栏模式 ("fixed", "normal", "auto")
|
||||
mobileHeaderMode = "auto"
|
||||
|
||||
# 主页信息设置
|
||||
## 主页模式 ("post", "other")
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
</div>
|
||||
|
||||
{{- /* Dynamic to top button */ -}}
|
||||
<a href="#" class="dynamic-to-top" id="dynamic-to-top">
|
||||
<a href="#" class="dynamic-to-top animated faster" id="dynamic-to-top">
|
||||
<span> </span>
|
||||
</a>
|
||||
|
||||
|
|
|
@ -42,3 +42,8 @@
|
|||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<script>
|
||||
window.desktopHeaderMode = {{ .Site.Params.desktopHeaderMode }};
|
||||
window.mobileHeaderMode = {{ .Site.Params.mobileHeaderMode }};
|
||||
</script>
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Add table
Reference in a new issue