feat: add loading progress bar
This commit is contained in:
parent
621b8b5071
commit
38bf8bc867
|
@ -5,21 +5,27 @@
|
|||
selectors: [
|
||||
'head title',
|
||||
'.page-container',
|
||||
'.pjax',
|
||||
'.pjax'
|
||||
],
|
||||
history: true,
|
||||
debug: false,
|
||||
cacheBust: false,
|
||||
timeout: 0,
|
||||
// analytics: false,
|
||||
// currentUrlFullReload: false,
|
||||
// scrollRestoration: false,
|
||||
analytics: false,
|
||||
currentUrlFullReload: false,
|
||||
scrollRestoration: false,
|
||||
// scrollTo: true,
|
||||
});
|
||||
|
||||
window.addEventListener('pjax:complete', () => {
|
||||
KEEP.refresh();
|
||||
|
||||
document.addEventListener('pjax:send', () => {
|
||||
KEEP.utils.loadingProgressBarStart();
|
||||
});
|
||||
|
||||
document.addEventListener('pjax:complete', () => {
|
||||
KEEP.utils.loadingProgressBarEnd();
|
||||
pjax.executeScripts(document.querySelectorAll('script[data-pjax], .pjax script'));
|
||||
KEEP.refresh();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<div class="progress-bar-container">
|
||||
<span class="scroll-progress-bar"></span>
|
||||
<span class="loading-progress-bar"></span>
|
||||
</div>
|
102
layout/page.ejs
102
layout/page.ejs
|
@ -1,59 +1,53 @@
|
|||
<div class="page-container">
|
||||
<%- partial('_partial/progress-bar') %>
|
||||
<main class="page-container">
|
||||
|
||||
<% if (theme.style.first_screen.enable === true && is_home() && !page.prev) { %>
|
||||
<%- partial('_partial/first-screen') %>
|
||||
<% } %>
|
||||
|
||||
<header class="page-header">
|
||||
<div class="header-progress"></div>
|
||||
</header>
|
||||
<div class="page-main-content">
|
||||
|
||||
<main class="page-main">
|
||||
|
||||
<div class="page-main-content">
|
||||
|
||||
<div class="page-main-content-top">
|
||||
<%- partial('_partial/header') %>
|
||||
</div>
|
||||
|
||||
<div class="page-main-content-middle">
|
||||
|
||||
<main class="main-content normal-code-theme">
|
||||
|
||||
<% if (is_home()) { %>
|
||||
<%- partial('home-content') %>
|
||||
|
||||
<% } else if (is_archive()) { %>
|
||||
<%- partial('archive-content') %>
|
||||
|
||||
<% } else if (is_post()) { %>
|
||||
<%- partial('article-content') %>
|
||||
|
||||
<% } else if (is_category()) { %>
|
||||
<%- partial('category-content') %>
|
||||
|
||||
<% } else if (is_tag()) { %>
|
||||
<%- partial('tag-content') %>
|
||||
|
||||
<% } else if (page.title === 'category' || page.title === 'categories') { %>
|
||||
<%- partial('category-list') %>
|
||||
|
||||
<% } else if (page.title === 'tag' || page.title === 'tags') { %>
|
||||
<%- partial('_partial/tagcloud') %>
|
||||
|
||||
<% } else { %>
|
||||
<%- partial('_partial/empty-page') %>
|
||||
|
||||
<% } %>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="page-main-content-bottom">
|
||||
<%- partial('_partial/footer') %>
|
||||
</div>
|
||||
<div class="page-main-content-top">
|
||||
<%- partial('_partial/header') %>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div class="page-main-content-middle">
|
||||
|
||||
<div class="main-content normal-code-theme">
|
||||
|
||||
<% if (is_home()) { %>
|
||||
<%- partial('home-content') %>
|
||||
|
||||
<% } else if (is_archive()) { %>
|
||||
<%- partial('archive-content') %>
|
||||
|
||||
<% } else if (is_post()) { %>
|
||||
<%- partial('article-content') %>
|
||||
|
||||
<% } else if (is_category()) { %>
|
||||
<%- partial('category-content') %>
|
||||
|
||||
<% } else if (is_tag()) { %>
|
||||
<%- partial('tag-content') %>
|
||||
|
||||
<% } else if (page.title === 'category' || page.title === 'categories') { %>
|
||||
<%- partial('category-list') %>
|
||||
|
||||
<% } else if (page.title === 'tag' || page.title === 'tags') { %>
|
||||
<%- partial('_partial/tagcloud') %>
|
||||
|
||||
<% } else { %>
|
||||
<%- partial('_partial/empty-page') %>
|
||||
|
||||
<% } %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="page-main-content-bottom">
|
||||
<%- partial('_partial/footer') %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% if (is_post()) { %>
|
||||
<div class="sidebar-tools">
|
||||
|
@ -66,19 +60,17 @@
|
|||
</div>
|
||||
|
||||
<% if (is_post() && theme.toc.enable === true) { %>
|
||||
<!-- page aside -->
|
||||
<aside class="page-aside">
|
||||
<%- partial('_partial/toc') %>
|
||||
</aside>
|
||||
<% } %>
|
||||
|
||||
<!-- image viewer -->
|
||||
<%- partial('_partial/image-viewer') %>
|
||||
|
||||
</div>
|
||||
<% if (theme.local_search.enable) { %>
|
||||
<%- partial('_partial/local-search') %>
|
||||
<% } %>
|
||||
|
||||
<% if (theme.local_search.enable) { %>
|
||||
<%- partial('_partial/local-search') %>
|
||||
<% } %>
|
||||
</main>
|
||||
|
||||
|
||||
|
|
|
@ -6,15 +6,15 @@
|
|||
// ========================================================================================
|
||||
// layout
|
||||
// ========================================================================================
|
||||
$header-height = 76px; // 头部默认高度
|
||||
$header-shrink-height = $header-height * 0.72; // 头部收缩高度
|
||||
$header-progress-height = 2.8px; // 头部进度条高度
|
||||
$main-content-width = 80%; // 中间内容区域宽度(PC)
|
||||
$main-content-width-tablet = 85%; // 中间内容区域宽度(平板)
|
||||
$main-content-width-mobile = 90%; // 中间内容区域宽度(手机)
|
||||
$circle-button-width = 40px; // tools 圆形工具按钮宽度
|
||||
$tools-button-width = 32px; // tools 方形工具按钮宽度
|
||||
$component-interspace = 30px; // 组件/模块的间隔值(PC)
|
||||
$header-height = 76px; // 头部默认高度
|
||||
$header-shrink-height = $header-height * 0.72; // 头部收缩高度
|
||||
$scroll-progress-bar-height = 2px; // 头部进度条高度
|
||||
$main-content-width = 80%; // 中间内容区域宽度(PC)
|
||||
$main-content-width-tablet = 85%; // 中间内容区域宽度(平板)
|
||||
$main-content-width-mobile = 90%; // 中间内容区域宽度(手机)
|
||||
$circle-button-width = 40px; // tools 圆形工具按钮宽度
|
||||
$tools-button-width = 32px; // tools 方形工具按钮宽度
|
||||
$component-interspace = 30px; // 组件/模块的间隔值(PC)
|
||||
$temp-content-max-width = hexo-config('style.content_max_width');
|
||||
$content-max-width = $temp-content-max-width ? convert($temp-content-max-width) : 1000px;
|
||||
|
||||
|
@ -22,8 +22,8 @@ $content-max-width = $temp-content-max-width ? convert($temp-content-max-width)
|
|||
// ========================================================================================
|
||||
// 媒体查询
|
||||
// ========================================================================================
|
||||
$media-max-width = 780px; // 媒体查询最大宽度 (平板)
|
||||
$media-max-width-mobile = 500px; // 媒体查询最大宽度(手机)
|
||||
$media-max-width = 780px; // 媒体查询最大宽度 (平板)
|
||||
$media-max-width-mobile = 500px; // 媒体查询最大宽度(手机)
|
||||
|
||||
keep-tablet()
|
||||
@media (max-width: $media-max-width)
|
||||
|
@ -75,6 +75,7 @@ $scroll-bar-bg-color = darken($background-color, 10%);
|
|||
$link-color = darken($default-text-color, 10%);
|
||||
$copyright-info-color = #CC0033;
|
||||
$avatar-background-color = #0066CC;
|
||||
$loading-progress-bar-color = #990000;
|
||||
|
||||
|
||||
// ========================================================================================
|
||||
|
@ -96,7 +97,8 @@ $dark-scroll-bar-color = darken($dark-background-color, 30%);
|
|||
$dark-scroll-bar-bg-color = lighten($dark-background-color, 10%);
|
||||
$dark-link-color = lighten($dark-default-text-color, 10%);
|
||||
$dark-copyright-info-color = darken($copyright-info-color, 20%);
|
||||
$dark-avatar-background-color = darken($avatar-background-color, 20%);
|
||||
$dark-avatar-background-color = darken($avatar-background-color, 10%);
|
||||
$dark-loading-progress-bar-color = lighten($loading-progress-bar-color, 50%);
|
||||
|
||||
|
||||
// ========================================================================
|
||||
|
@ -129,6 +131,7 @@ root-color(mode) {
|
|||
--link-color: mode == 'light' ? $link-color : $dark-link-color;
|
||||
--copyright-info-color: mode == 'light' ? $copyright-info-color : $dark-copyright-info-color;
|
||||
--avatar-background-color: mode == 'light' ? $avatar-background-color : $dark-avatar-background-color;
|
||||
--loading-progress-bar-color: mode == 'light' ? $loading-progress-bar-color : $dark-loading-progress-bar-color;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -10,14 +10,14 @@ $first-screen-img = $temp-img ? $temp-img:'/images/bg.svg';
|
|||
width: 100%;
|
||||
overflow: hidden;
|
||||
background: url($first-screen-img) center center / cover no-repeat;
|
||||
background-position-y: $header-height - $header-progress-height;
|
||||
background-position-y: $header-height - $scroll-progress-bar-height;
|
||||
|
||||
+keep-tablet() {
|
||||
background-position-y: $header-height * 0.9 - $header-progress-height;
|
||||
background-position-y: $header-height * 0.9 - $scroll-progress-bar-height;
|
||||
}
|
||||
|
||||
+keep-mobile() {
|
||||
background-position-y: $header-height * 0.8 - $header-progress-height;
|
||||
background-position-y: $header-height * 0.8 - $scroll-progress-bar-height;
|
||||
}
|
||||
|
||||
.content {
|
||||
|
|
|
@ -10,7 +10,7 @@ $menu-bar-line-height = 2.5px;
|
|||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--background-color);
|
||||
padding-top: $header-progress-height;
|
||||
padding-top: $scroll-progress-bar-height;
|
||||
transition();
|
||||
|
||||
hover-style(1.02, 1.02);
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
.progress-bar-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: $z-index-9;
|
||||
|
||||
.loading-progress-bar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 1px;
|
||||
width: 0;
|
||||
background: var(--loading-progress-bar-color);
|
||||
box-shadow: 0 1px 3px var(--loading-progress-bar-color);
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
z-index: $z-index-8;
|
||||
transition();
|
||||
|
||||
&.show {
|
||||
transition();
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.scroll-progress-bar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 0;
|
||||
height: $scroll-progress-bar-height;
|
||||
visibility: hidden;
|
||||
background: var(--primary-color);
|
||||
transition: all 0.1s ease;
|
||||
z-index: $z-index-7;
|
||||
|
||||
&.hide {
|
||||
transition: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,135 +1,114 @@
|
|||
$temp-width = hexo-config('style.left_side_width');
|
||||
$page-aside-width = $temp-width ? convert($temp-width):260px;
|
||||
$page-aside-width = $temp-width ? convert($temp-width) : 260px;
|
||||
|
||||
.page-container {
|
||||
position: relative;
|
||||
padding-top: $header-progress-height;
|
||||
|
||||
transition();
|
||||
|
||||
+keep-tablet() {
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
.page-main-content {
|
||||
padding-top: $header-height;
|
||||
position: relative;
|
||||
|
||||
.page-header {
|
||||
.header-progress {
|
||||
visibility: hidden;
|
||||
position: fixed;
|
||||
width: 0;
|
||||
height: $header-progress-height;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background: var(--primary-color);
|
||||
transition: all 0.1s ease;
|
||||
z-index: $z-index-7;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.page-main {
|
||||
|
||||
.page-main-content {
|
||||
padding-top: $header-height;
|
||||
position: relative;
|
||||
|
||||
.header-shrink & {
|
||||
padding-top: $header-shrink-height;
|
||||
transition();
|
||||
|
||||
+keep-tablet() {
|
||||
padding-top: $header-shrink-height * 0.9;
|
||||
}
|
||||
|
||||
+keep-mobile() {
|
||||
padding-top: $header-shrink-height * 0.8;
|
||||
}
|
||||
}
|
||||
.header-shrink & {
|
||||
padding-top: $header-shrink-height;
|
||||
transition();
|
||||
|
||||
+keep-tablet() {
|
||||
padding-top: $header-height * 0.9;
|
||||
padding-top: $header-shrink-height * 0.9;
|
||||
}
|
||||
|
||||
+keep-mobile() {
|
||||
padding-top: $header-height * 0.8;
|
||||
padding-top: $header-shrink-height * 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
+keep-tablet() {
|
||||
padding-top: $header-height * 0.9;
|
||||
}
|
||||
|
||||
+keep-mobile() {
|
||||
padding-top: $header-height * 0.8;
|
||||
}
|
||||
|
||||
.page-main-content-top {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: $header-height;
|
||||
z-index: $z-index-5;
|
||||
box-sizing: border-box;
|
||||
transition();
|
||||
|
||||
&.hide {
|
||||
transform: translateY(-102%);
|
||||
}
|
||||
|
||||
.page-main-content-top {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: $header-height;
|
||||
z-index: $z-index-5;
|
||||
.header-shrink & {
|
||||
height: $header-shrink-height;
|
||||
|
||||
+keep-tablet() {
|
||||
height: $header-shrink-height * 0.9;
|
||||
}
|
||||
|
||||
+keep-mobile() {
|
||||
height: $header-shrink-height * 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+keep-tablet() {
|
||||
height: $header-height * 0.9;
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
|
||||
+keep-mobile() {
|
||||
height: $header-height * 0.8;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.page-main-content-middle {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: $component-interspace 0;
|
||||
|
||||
+keep-tablet() {
|
||||
padding: $component-interspace * 0.8 0;
|
||||
}
|
||||
|
||||
+keep-mobile() {
|
||||
padding: $component-interspace * 0.6 0;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
width: $main-content-width;
|
||||
max-width: $content-max-width;
|
||||
height: 100%;
|
||||
transition();
|
||||
|
||||
&.hide {
|
||||
transform: translateY(-102%);
|
||||
}
|
||||
|
||||
.header-shrink & {
|
||||
height: $header-shrink-height;
|
||||
|
||||
+keep-tablet() {
|
||||
height: $header-shrink-height * 0.9;
|
||||
}
|
||||
|
||||
+keep-mobile() {
|
||||
height: $header-shrink-height * 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+keep-tablet() {
|
||||
height: $header-height * 0.9;
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
|
||||
+keep-mobile() {
|
||||
height: $header-height * 0.8;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.page-main-content-middle {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: $component-interspace 0;
|
||||
|
||||
+keep-tablet() {
|
||||
padding: $component-interspace * 0.8 0;
|
||||
width: $main-content-width-tablet;
|
||||
}
|
||||
|
||||
+keep-mobile() {
|
||||
padding: $component-interspace * 0.6 0;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
width: $main-content-width;
|
||||
max-width: $content-max-width;
|
||||
height: 100%;
|
||||
transition();
|
||||
|
||||
+keep-tablet() {
|
||||
width: $main-content-width-tablet;
|
||||
}
|
||||
|
||||
+keep-mobile() {
|
||||
width: $main-content-width-mobile;
|
||||
}
|
||||
width: $main-content-width-mobile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.page-main-content-bottom {
|
||||
width: 100%;
|
||||
}
|
||||
.page-main-content-bottom {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
@import "layout/_partial/local-search.styl"
|
||||
@import "layout/_partial/toc.styl"
|
||||
@import "layout/_partial/comment/comment.styl"
|
||||
@import "layout/_partial/progress-bar.styl"
|
||||
@import "layout/_partial/header.styl"
|
||||
@import "layout/_partial/tools.styl"
|
||||
@import "layout/_partial/side-tools.styl"
|
||||
|
|
|
@ -4,11 +4,13 @@ KEEP.initUtils = () => {
|
|||
|
||||
html_root_dom: document.querySelector('html'),
|
||||
pageContainer_dom: document.querySelector('.page-container'),
|
||||
headerProgress_dom: document.querySelector('.header-progress'),
|
||||
pageTop_dom: document.querySelector('.page-main-content-top'),
|
||||
firstScreen_dom: document.querySelector('.first-screen-container'),
|
||||
scrollProgressBar_dom: document.querySelector('.scroll-progress-bar'),
|
||||
loadingProgressBar_dom: document.querySelector('.loading-progress-bar'),
|
||||
|
||||
innerHeight: window.innerHeight,
|
||||
loadingProgressBarTimer: null,
|
||||
prevScrollValue: 0,
|
||||
defaultFontSize: 0,
|
||||
|
||||
|
@ -31,9 +33,9 @@ KEEP.initUtils = () => {
|
|||
const percent = Math.round(scrollTop / (scrollHeight - clientHeight) * 100).toFixed(0);
|
||||
const ProgressPercent = (scrollTop / (scrollHeight - clientHeight) * 100).toFixed(3);
|
||||
|
||||
if (this.headerProgress_dom) {
|
||||
this.headerProgress_dom.style.visibility = percent === '0' ? 'hidden' : 'visible';
|
||||
this.headerProgress_dom.style.width = `${ProgressPercent}%`;
|
||||
if (this.scrollProgressBar_dom) {
|
||||
this.scrollProgressBar_dom.style.visibility = percent === '0' ? 'hidden' : 'visible';
|
||||
this.scrollProgressBar_dom.style.width = `${ProgressPercent}%`;
|
||||
}
|
||||
|
||||
// hide header handle
|
||||
|
@ -125,7 +127,7 @@ KEEP.initUtils = () => {
|
|||
});
|
||||
},
|
||||
|
||||
// go comment
|
||||
// go comment anchor
|
||||
goComment() {
|
||||
this.goComment_dom = document.querySelector('.go-comment');
|
||||
if (this.goComment_dom) {
|
||||
|
@ -150,12 +152,10 @@ KEEP.initUtils = () => {
|
|||
// init page height handle
|
||||
initPageHeightHandle() {
|
||||
if (this.firstScreen_dom) return;
|
||||
|
||||
const temp_h1 = this.getElementHeight('.header-progress');
|
||||
const temp_h2 = this.getElementHeight('.page-main-content-top');
|
||||
const temp_h3 = this.getElementHeight('.page-main-content-middle');
|
||||
const temp_h4 = this.getElementHeight('.page-main-content-bottom');
|
||||
const allDomHeight = temp_h1 + temp_h2 + temp_h3 + temp_h4;
|
||||
const temp_h1 = this.getElementHeight('.page-main-content-top');
|
||||
const temp_h2 = this.getElementHeight('.page-main-content-middle');
|
||||
const temp_h3 = this.getElementHeight('.page-main-content-bottom');
|
||||
const allDomHeight = temp_h1 + temp_h2 + temp_h3;
|
||||
const innerHeight = window.innerHeight;
|
||||
const pb_dom = document.querySelector('.page-main-content-bottom');
|
||||
if (allDomHeight < innerHeight) {
|
||||
|
@ -245,6 +245,37 @@ KEEP.initUtils = () => {
|
|||
post && post.forEach(v => {
|
||||
v.innerHTML = this.getHowLongAgo(Date.now() - new Date(v.dataset.date).getTime())
|
||||
})
|
||||
},
|
||||
|
||||
// loading progress bar start
|
||||
loadingProgressBarStart() {
|
||||
this.loadingProgressBarTimer && clearInterval(this.loadingProgressBarTimer);
|
||||
this.loadingProgressBar_dom.style.width = '0';
|
||||
this.scrollProgressBar_dom.classList.add('hide');
|
||||
|
||||
let width = 20;
|
||||
const maxWidth = 95;
|
||||
|
||||
this.loadingProgressBar_dom.classList.add('show');
|
||||
this.loadingProgressBar_dom.style.width = width + '%';
|
||||
|
||||
this.loadingProgressBarTimer = setInterval(() => {
|
||||
width += parseInt((Math.random() * 10).toFixed(2));
|
||||
if (width > maxWidth) width = maxWidth;
|
||||
this.loadingProgressBar_dom.style.width = width + '%';
|
||||
}, 100);
|
||||
},
|
||||
|
||||
// loading progress bar end
|
||||
loadingProgressBarEnd() {
|
||||
this.loadingProgressBarTimer && clearInterval(this.loadingProgressBarTimer);
|
||||
this.loadingProgressBar_dom.style.width = '100%';
|
||||
|
||||
const tempTimeout = setTimeout(() => {
|
||||
this.loadingProgressBar_dom.classList.remove('show');
|
||||
this.scrollProgressBar_dom.classList.remove('hide');
|
||||
clearTimeout(tempTimeout);
|
||||
}, 200);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue