提交 1eef9320 编写于 作者: EvanOne(文一)'s avatar EvanOne(文一)

refactor: Optimize theme performance & remove some config

1. remove style to the browser progress bar.
2. remove the animation configuration item of the back2top button.
上级 60d9af5c
...@@ -35,12 +35,11 @@ Please don`t open an issue that is not related to the theme, otherwise, it will ...@@ -35,12 +35,11 @@ Please don`t open an issue that is not related to the theme, otherwise, it will
## Actual behaviour <!-- 实际行为 --> ## Actual behaviour <!-- 实际行为 -->
<!-- Please give me the screenshots to locate the issue --> <!-- Please give me the screenshots to locate the issue -->
<!-- 请尽量提供截图来定位问题 --> <!-- 请尽量提供截图来定位问题 -->
## Steps to reproduce the behaviour <!-- 重现步骤 --> ## Steps to reproduce the behaviour <!-- 重现步骤 -->
......
...@@ -91,8 +91,6 @@ back2top: ...@@ -91,8 +91,6 @@ back2top:
# Icon name in FontAwesome, see: https://fontawesome.com/v4.7.0/icons/ # Icon name in FontAwesome, see: https://fontawesome.com/v4.7.0/icons/
# `rocket` is recommended. # `rocket` is recommended.
name: rocket name: rocket
# Animation of rocket launch.
animation: true
# Rotation Angle of icon. # Rotation Angle of icon.
rotate: -45deg rotate: -45deg
# Please use quote to wrap value (All CSS size units are supported). # Please use quote to wrap value (All CSS size units are supported).
...@@ -126,7 +124,7 @@ footer: ...@@ -126,7 +124,7 @@ footer:
# `heart` is recommended with animation in red (#ff0000). # `heart` is recommended with animation in red (#ff0000).
name: heart name: heart
# Heart beat animation. # Heart beat animation.
animation: true animation: false
# Please use quote to wrap value (All CSS size units are supported). # Please use quote to wrap value (All CSS size units are supported).
color: '#ff0000' color: '#ff0000'
# Hexo link (Powered by Hexo). # Hexo link (Powered by Hexo).
...@@ -215,7 +213,7 @@ toc: ...@@ -215,7 +213,7 @@ toc:
# Maximum heading depth of generated toc. You can set it in the # Maximum heading depth of generated toc. You can set it in the
# post through `toc_max_depth` in Front-matter. # post through `toc_max_depth` in Front-matter.
# e.g. value: 3, will use h1~3 to generated toc. # e.g. value: 3, will use h1~3 to generated toc.
max_depth: 6 max_depth: 4
# Subscribe of email and rss. # Subscribe of email and rss.
feed: feed:
...@@ -685,7 +683,9 @@ cdn: ...@@ -685,7 +683,9 @@ cdn:
# See: https://fontawesome.com/ # See: https://fontawesome.com/
# Example: # Example:
# fontawesome: //cdn.jsdelivr.net/npm/font-awesome@4/css/font-awesome.min.css # fontawesome: //cdn.jsdelivr.net/npm/font-awesome@4/css/font-awesome.min.css
# fontawesome: //cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.10.2/css/all.min.css
# fontawesome: //cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css # fontawesome: //cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css
# fontawesome: //cdnjs.cloudflare.com/ajax/libs/font-awesome/5.10.2/css/all.min.css
fontawesome: fontawesome:
# Using version: 3.4.1 # Using version: 3.4.1
...@@ -782,7 +782,7 @@ cdn: ...@@ -782,7 +782,7 @@ cdn:
# lazyload: //cdn.jsdelivr.net/npm/lazyload@2.0.0-rc.2/lazyload.min.js # lazyload: //cdn.jsdelivr.net/npm/lazyload@2.0.0-rc.2/lazyload.min.js
lazyload: lazyload:
# # Using version: latest # Using version: latest
# See: https://github.com/GoogleChromeLabs/quicklink/ # See: https://github.com/GoogleChromeLabs/quicklink/
# Example: # Example:
# quicklink: //cdn.jsdelivr.net/npm/quicklink@latest/dist/quicklink.umd.js # quicklink: //cdn.jsdelivr.net/npm/quicklink@latest/dist/quicklink.umd.js
......
...@@ -106,7 +106,7 @@ prompt: ...@@ -106,7 +106,7 @@ prompt:
success: Copy Success success: Copy Success
error: Copy Error error: Copy Error
creative_commons: Creative Commons creative_commons: Creative Commons
copy_code: Copy Code copy_button: Click to Copy
# Others # Others
creative_commons: Creative Commons creative_commons: Creative Commons
...@@ -106,7 +106,7 @@ prompt: ...@@ -106,7 +106,7 @@ prompt:
success: 复制成功 success: 复制成功
error: 复制失败 error: 复制失败
creative_commons: 知识共享 creative_commons: 知识共享
copy_code: 复制代码 copy_button: 点击复制
# 其他 # 其他
creative_commons: 知识共享 creative_commons: 知识共享
...@@ -18,7 +18,8 @@ ...@@ -18,7 +18,8 @@
var sidebar = "undefined"; var sidebar = "undefined";
if (theme.sidebar.enable) { if (theme.sidebar.enable) {
sidebar = JSON.stringify({ sidebar = JSON.stringify({
offsetTop: theme.sidebar.offsetTop offsetTop: theme.sidebar.offsetTop,
renderTocDepth: theme.toc.max_depth
}); });
} }
...@@ -63,7 +64,7 @@ ...@@ -63,7 +64,7 @@
copy_success: _p("prompt.copy.success"), copy_success: _p("prompt.copy.success"),
copy_error: _p("prompt.copy.error"), copy_error: _p("prompt.copy.error"),
creative_commons: _p("prompt.creative_commons"), creative_commons: _p("prompt.creative_commons"),
copy_code: _p("prompt.copy_code") copy_button: _p("prompt.copy_button")
}); });
script. script.
......
include ../_mixins/multi-menu.pug include ../_mixins/multi-menu.pug
header#header( header#header
style=`background-image: url(${ div.loading-bar
page.top_image ? page.top_image : div.progress
theme.header.bg_image.enable ?
theme.header.bg_image.url : " " nav.header-nav
})`
)
nav.header-nav.slider-up
div.header-nav-inner div.header-nav-inner
div.fa.fa-bars.header-nav-menu-icon div.fa.fa-bars.header-nav-menu-icon
......
...@@ -25,4 +25,4 @@ script. ...@@ -25,4 +25,4 @@ script.
language: '!{ lang }' language: '!{ lang }'
}); });
gitalk.render('gitalk-container'); gitalk.render('gitalk-container');
}); }, false);
...@@ -36,4 +36,4 @@ script. ...@@ -36,4 +36,4 @@ script.
} else { } else {
renderGitment(); renderGitment();
} }
}); }, false);
...@@ -9,4 +9,4 @@ script. ...@@ -9,4 +9,4 @@ script.
j.async = true; j.async = true;
e.parentNode.insertBefore(j, e); e.parentNode.insertBefore(j, e);
})(document, 'script'); })(document, 'script');
}); }, false);
...@@ -31,4 +31,4 @@ script. ...@@ -31,4 +31,4 @@ script.
recordIP: !{ theme.valine.recordIP }, recordIP: !{ theme.valine.recordIP },
lang: '!{ theme.valine.language }' || 'zh-cn' lang: '!{ theme.valine.language }' || 'zh-cn'
}); });
}); }, false);
...@@ -22,7 +22,7 @@ if theme.quicklink.enable ...@@ -22,7 +22,7 @@ if theme.quicklink.enable
} }
if (!{theme.quicklink.delay}) { if (!{theme.quicklink.delay}) {
window.addEventListener('load', initQuicklink); window.addEventListener('load', initQuicklink, false);
} else { } else {
initQuicklink(); initQuicklink();
} }
...@@ -253,4 +253,4 @@ if theme.local_search.enable ...@@ -253,4 +253,4 @@ if theme.local_search.enable
duration: 300 duration: 300
}); });
} }
}); }, false);
#footer #footer
background-color: $gray-dark background-color: $gray-dark
background-attachment: fixed
background-position: bottom
background-size: cover background-size: cover
if (hexo-config('footer.bg_image.enable')) if (hexo-config('footer.bg_image.enable'))
background-image: url(hexo-config('footer.bg_image.url') || ' ') background: url(hexo-config('footer.bg_image.url') || ' ') no-repeat center center
a a
clearAStyle() clearAStyle()
...@@ -25,4 +23,4 @@ ...@@ -25,4 +23,4 @@
.heart-beat .heart-beat
font-size: .9em font-size: .9em
animation: footer-heart-beat 1.4s infinite animation: footer-heart-beat 1.2s infinite
...@@ -8,11 +8,13 @@ else ...@@ -8,11 +8,13 @@ else
height: $header-height height: $header-height
font-size: $font-header-base font-size: $font-header-base
background-color: $gray-dark background-color: $gray-dark
background-repeat: no-repeat
background-attachment: fixed
background-position: center
background-size: cover background-size: cover
transition: height .5s
if (hexo-config('page.top_image'))
background: url(hexo-config('page.top_image') || ' ') no-repeat center center
if (hexo-config('header.bg_image.enable'))
background: url(hexo-config('header.bg_image.url') || ' ') no-repeat center center
if (hexo-config('header.nav_height') && match('%', hexo-config('header.nav_height'))) if (hexo-config('header.nav_height') && match('%', hexo-config('header.nav_height')))
$header-nav-height = unit(convert(hexo-config('header.nav_height')), 'vh') $header-nav-height = unit(convert(hexo-config('header.nav_height')), 'vh')
...@@ -25,19 +27,17 @@ else ...@@ -25,19 +27,17 @@ else
z-index: $z-index1 z-index: $z-index1
width: 100% width: 100%
height: $header-nav-height height: $header-nav-height
transition: background-color .3s transition: transform .3s, background-color .3s
animation-duration: .3s will-change: transform
animation-timing-function: ease
animation-fill-mode: both
&.fixed &.fixed
background-color: $header-nav-bg-color background-color: $header-nav-bg-color
&.slider-down &.slider-down
animation-name: header-sliderDown transform: translateY(0)
&.slider-up &.slider-up
animation-name: header-sliderUp transform: translateY(-100%)
$header-nav-link-color $header-nav-link-color
color: $header-nav-link-color color: $header-nav-link-color
......
...@@ -10,6 +10,7 @@ $sidebar-width = convert(hexo-config('sidebar.width') || '300px') ...@@ -10,6 +10,7 @@ $sidebar-width = convert(hexo-config('sidebar.width') || '300px')
width: $sidebar-width width: $sidebar-width
font-size: $font-sidebar-base font-size: $font-sidebar-base
background-color: $white background-color: $white
transform: translateZ(0)
&.sticky &.sticky
position: fixed position: fixed
...@@ -241,6 +242,7 @@ $avatar-animation = 'avatar-' + convert(hexo-config('author.avatar.animation') | ...@@ -241,6 +242,7 @@ $avatar-animation = 'avatar-' + convert(hexo-config('author.avatar.animation') |
clearImgStyle() clearImgStyle()
.sidebar-progress .sidebar-progress
overflow: hidden
margin-top: .5em margin-top: .5em
text-align: center text-align: center
...@@ -251,6 +253,8 @@ $avatar-animation = 'avatar-' + convert(hexo-config('author.avatar.animation') | ...@@ -251,6 +253,8 @@ $avatar-animation = 'avatar-' + convert(hexo-config('author.avatar.animation') |
margin: 0 .1em margin: 0 .1em
&-line &-line
width: 0 width: 100%
height: convert(hexo-config('reading_progress.height') || '1px') height: convert(hexo-config('reading_progress.height') || '1px')
background-color: convert(hexo-config('reading_progress.color') || '$blue-light') background-color: convert(hexo-config('reading_progress.color') || '$blue-light')
transition: transform .3s
transform: translateX(-100%)
#back-top #back-top
visibility: hidden
position: fixed position: fixed
right: 1.5rem right: 0
bottom: 5vh bottom: 5vh
transition: transform .5s
transform: translateX(100%)
&.show
transform: translateX(-100%)
&.hide
transform: translateX(100%)
$back-to-top-rotate = convert(hexo-config('back2top.icon.rotate') || '0') $back-to-top-rotate = convert(hexo-config('back2top.icon.rotate') || '0')
$back-to-top-color = convert(hexo-config('back2top.icon.color') || '#666') $back-to-top-color = convert(hexo-config('back2top.icon.color') || '#666')
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
@import './external-link.styl' if (hexo-config('external_link.icon.enable')) @import './external-link.styl' if (hexo-config('external_link.icon.enable'))
@import './fancybox.styl' if (hexo-config('fancybox')) @import './fancybox.styl' if (hexo-config('fancybox'))
@import './lazyload.styl' if (hexo-config('lazyload.enable')) @import './lazyload.styl' if (hexo-config('lazyload.enable'))
@import './loading-bar.styl'
@import './recent-posts.styl' @import './recent-posts.styl'
@import './pagination.styl' @import './pagination.styl'
@import './comments.styl' @import './comments.styl'
......
.loading-bar
position: fixed
top: 0
left: 0
z-index: 99999
opacity: 0
transition: opacity .4s
.progress
position: fixed
top: 0
left: 0
width: 100%
height: 2px
background: #77b6ff
box-shadow: 0 0 10px rgba(119, 182, 255, .7)
transform: translateX(-100%)
&.loading
opacity: 1
transition: none
.progress
transition: transform .4s ease
will-change: transform
// header nav slider animation
// ----------------------------------------
@keyframes header-sliderDown
0%
transform: translateY(-100%)
100%
transform: translateY(0)
@keyframes header-sliderUp
0%
transform: translateY(0)
100%
transform: translateY(-100%)
// avatar animation // avatar animation
// ---------------------------------------- // ----------------------------------------
if (hexo-config('author.enable')) if (hexo-config('author.enable'))
......
...@@ -2,15 +2,13 @@ ...@@ -2,15 +2,13 @@
color: $selection-color color: $selection-color
background: $selection-bg background: $selection-bg
:root
box-sizing: border-box
*, *,
*::before, *::before,
*::after *::after
box-sizing: inherit box-sizing: inherit
html html
box-sizing: border-box
font-size: $font-size-rem font-size: $font-size-rem
line-height: 100% line-height: 100%
...@@ -27,8 +25,7 @@ a ...@@ -27,8 +25,7 @@ a
border-bottom: 1px solid $link-bottom-color border-bottom: 1px solid $link-bottom-color
text-decoration: none text-decoration: none
color: $link-color color: $link-color
outline: none transition: .2s color ease, .2s border-bottom ease
transition: .2s all ease
cursor: pointer cursor: pointer
&:hover &:hover
......
@import './scroll.styl'
@import './base.styl' @import './base.styl'
@import './animation.styl' @import './animation.styl'
@import './utils.styl' @import './utils.styl'
html::-webkit-scrollbar
width: 10px
.sidebar-toc::-webkit-scrollbar
width: 4px
::-webkit-scrollbar-track
background-color: #fff
::-webkit-scrollbar-thumb
background-color: rgba(0, 0, 0, .2)
::-webkit-scrollbar-thumb:hover
background-color: rgba(0, 0, 0, .3)
::-webkit-scrollbar-thumb:window-inactive
background-color: #a0daff
...@@ -65,7 +65,7 @@ $img-border-color = #dadefb ...@@ -65,7 +65,7 @@ $img-border-color = #dadefb
// Module`s color // Module`s color
// ------------------------------------------- // -------------------------------------------
// Header // Header
$header-nav-bg-color = alpha($black-dark, .8) $header-nav-bg-color = alpha(#2d2e30, .6)
$header-nav-text-color = $white-light $header-nav-text-color = $white-light
$header-nav-text-hover-color = $blue-light $header-nav-text-hover-color = $blue-light
$header-nav-link-color = $white-light $header-nav-link-color = $white-light
......
$(document).ready(function () {
var CODEBLOCK_CLASS_NAME = 'highlight';
var $codeBlocks = $('figure.highlight');
$codeBlocks.each(function () {
if (!$(this).find('figcaption')[0]) {
var lang = this
.getAttribute('class')
.split(/\s/)
.filter(function (e) { return e !== CODEBLOCK_CLASS_NAME; });
var codeHeader = $(
'<figcaption class="custom">' +
'<div class="custom-lang">' + lang + '</div>' +
'</figcaption>'
)[0];
this.insertBefore(codeHeader, $(this).children().first()[0]);
}
});
var $copyIcon = $(
'<div class="copy-button" data-popover=' +
CONFIG.prompt.copy_code +
' data-popover-pos="up">' +
'<i class="fa fa-clipboard"></i>' +
'</div>'
);
var COPY_BUTTON_WRAPPER =
'figure.highlight figcaption, .post-copyright';
// Add a copy button to the selected elements.
$(COPY_BUTTON_WRAPPER).append($copyIcon);
$('.copy-button').on('click', function () {
var container = null;
var codeContainer =
$(this).parent('figcaption').parent('figure').find('td.code')[0];
if (codeContainer) { // Copy code.
container = codeContainer;
} else { // Copy text.
container = $(this).parent()[0];
}
if (Stun.utils.copyText(container)) {
Stun.utils.popAlert('success', CONFIG.prompt.copy_success);
} else {
Stun.utils.popAlert('error', CONFIG.prompt.copy_error);
}
});
});
$(document).ready(function () { $(document).ready(function () {
// The previous distance from the page to the top. // The previous distance from the page to the top.
var prevScrollTop = 0; var prevScrollTop = 0;
var isNavFix = false;
// Initial run. var isNavShow = true;
headerNavScroll();
$(window).scroll(function () {
headerNavScroll();
});
// Click the heading.
$('.content')
.find('h1,h2,h3,h4,h5,h6')
.on('click', function () {
scrollHeadingToTop('#' + $(this).attr('id'));
});
// Click the post toc.
$('.toc-link').on('click', function (e) {
e.preventDefault();
scrollHeadingToTop($(this).attr('href'));
});
function headerNavScroll () { function headerNavScroll () {
var scrollTop = $(window).scrollTop(); var scrollTop = $(window).scrollTop();
...@@ -30,18 +12,28 @@ $(document).ready(function () { ...@@ -30,18 +12,28 @@ $(document).ready(function () {
$('.header-nav').removeClass('fixed'); $('.header-nav').removeClass('fixed');
$('.header-nav').removeClass('slider-up'); $('.header-nav').removeClass('slider-up');
$('.header-nav').addClass('slider-down'); $('.header-nav').addClass('slider-down');
isNavFix = false;
} else { } else {
$('.header-nav').addClass('fixed'); if (!isNavFix) {
$('.header-nav').addClass('fixed');
if (delta > 0) { isNavFix = true;
if (Math.abs(delta) > 5) { }
var MIN_SCROLL_TO_CHANGE_NAV = 5;
// Make the state of nav bar not change due to tiny scrolling.
if (Math.abs(delta) > MIN_SCROLL_TO_CHANGE_NAV) {
if (isNavShow && delta > 0) {
$('.header-nav').removeClass('slider-down'); $('.header-nav').removeClass('slider-down');
$('.header-nav').addClass('slider-up'); $('.header-nav').addClass('slider-up');
}
} else { isNavShow = false;
if (Math.abs(delta) > 5) { } else if (!isNavShow && delta < 0) {
$('.header-nav').removeClass('slider-up'); $('.header-nav').removeClass('slider-up');
$('.header-nav').addClass('slider-down'); $('.header-nav').addClass('slider-down');
isNavShow = true;
} }
} }
} }
...@@ -54,4 +46,55 @@ $(document).ready(function () { ...@@ -54,4 +46,55 @@ $(document).ready(function () {
.velocity('stop') .velocity('stop')
.velocity('scroll', { easing: 'easeOutSine' }); .velocity('scroll', { easing: 'easeOutSine' });
} }
var isBack2topShow = false;
// Back the page to top.
function back2top () {
function back2topHandler () {
var $top = $('#back-top');
var scrollTop = $(window).scrollTop();
if (scrollTop !== 0) {
if (!isBack2topShow) {
$top.addClass('show');
$top.removeClass('hide');
isBack2topShow = true;
}
} else {
$top.addClass('hide');
$top.removeClass('show');
isBack2topShow = false;
}
}
$(window).on('load', back2topHandler);
$(window).on('scroll', Stun.utils.throttle(function () {
back2topHandler();
}, 500));
$('#back-top').on('click', function () {
$('body').velocity('stop').velocity('scroll');
});
}
// Initialization
headerNavScroll();
back2top();
$(window).on('scroll', Stun.utils.throttle(function () {
headerNavScroll();
}, 100));
// Click the heading.
$('.content')
.find('h1,h2,h3,h4,h5,h6')
.on('click', function () {
scrollHeadingToTop('#' + $(this).attr('id'));
});
// Click the post toc.
$('.toc-link').on('click', function (e) {
e.preventDefault();
scrollHeadingToTop($(this).attr('href'));
});
}); });
$(document).ready(function () { $(document).ready(function () {
var $toc = $('.sidebar-toc');
var $view = $('.sidebar-overview');
// The heading that reached the top currently. // The heading that reached the top currently.
var currHeading = null; var currHeading = null;
// The heading that reached the top last time. // The heading that reached the top last time.
var lastHeading = null; var lastHeading = null;
var isRemoveTocClass = false;
// Whether toc needs scrolling. var tocDepth = CONFIG.sidebar.renderTocDepth;
var isTocScroll = false; // Optimize selector by theme config.
var HEADING_SELECTOR = 'h1,h2,h3,h4,h5,h6'.slice(0, tocDepth * 3);
// Distance from sidebar to top. var $postBody = $('.post-body');
var SIDEBAR_STICKY_TOP = parseInt(CONFIG.sidebar.offsetTop); var $allTocItem = $('.sidebar-toc li');
// Is toc in anime. if (tocDepth !== 6) {
var isAnime = false; HEADING_SELECTOR = HEADING_SELECTOR.slice(0, -1);
// Is toc in max heihgt. }
var isMaxH = true;
// Initial run
autoSpreadToc();
scrollTocToMiddle();
sidebarSticky();
sidebarAdjustHeight();
readProgress();
$(window).scroll(function () {
autoSpreadToc();
scrollTocToMiddle();
sidebarSticky();
sidebarAdjustHeight();
readProgress();
});
$('.sidebar-nav-toc').on('click', function () {
$('.sidebar-nav-toc').toggleClass('current');
$('.sidebar-nav-overview').toggleClass('current');
$toc.css('display', 'block');
$toc.velocity('fadeIn');
$view.css('display', 'none');
$view.velocity('fadeOut');
});
$('.sidebar-nav-overview').on('click', function () {
$('.sidebar-nav-toc').toggleClass('current');
$('.sidebar-nav-overview').toggleClass('current');
$toc.css('display', 'none');
$toc.velocity('fadeOut');
$view.css('display', 'block');
$view.velocity('fadeIn');
});
// Automatically expand items in the article directory // Automatically expand items in the article directory
// based on the scrolling of heading in the article. // based on the scrolling of heading in the article.
function autoSpreadToc () { function autoSpreadToc () {
var $postBody = $('.post-body'); var $headings = $postBody.find(HEADING_SELECTOR);
var $headings = $postBody.find('h1,h2,h3,h4,h5,h6');
var $firsetChild = $headings.first(); var $firsetChild = $headings.first();
$headings.each(function () {
var headingTop = this.getBoundingClientRect().top;
if (headingTop < 0) {
currHeading = this.getAttribute('id');
}
});
// All heading are not to the top. // All heading are not to the top.
if ($postBody[0] && (!!$firsetChild[0] && if ($postBody[0] && (!!$firsetChild[0] &&
$firsetChild.offset().top - $(window).scrollTop() > 0)) { $firsetChild.offset().top - $(window).scrollTop() > 0)) {
$('.sidebar-toc li').removeClass('active current'); if (!isRemoveTocClass) {
$allTocItem.removeClass('active current');
isRemoveTocClass = true;
}
return; return;
} else {
isRemoveTocClass = false;
} }
$headings.each(function () {
if (this.getBoundingClientRect().top < 0) {
currHeading = $(this).attr('id');
}
});
if (currHeading !== lastHeading) { if (currHeading !== lastHeading) {
var targetLink = $('.sidebar-toc a[href="#' + currHeading + '"]'); var targetLink = $('.sidebar-toc a[href="#' + currHeading + '"]');
// If the relevant "<a>" is not found, remain the state of the toc, // If the relevant "<a>" is not found, remain the state of the toc,
// either, remove styles for all active states. // either, remove styles for all active states.
if (targetLink[0]) { if (targetLink[0]) {
$('.sidebar-toc li').removeClass('active current'); $allTocItem.removeClass('active current');
} }
targetLink.parents('li').addClass('active'); targetLink.parents('li').addClass('active');
targetLink.parent().addClass('current'); targetLink.parent().addClass('current');
lastHeading = currHeading; lastHeading = currHeading;
} }
} }
// Whether toc needs scrolling.
var isTocScroll = false;
// Scroll the post toc to the middle. // Scroll the post toc to the middle.
function scrollTocToMiddle () { function scrollTocToMiddle () {
var $toc = $('.sidebar-toc'); var $tocWrapperHeight = $('.sidebar-toc').height();
var $currLink = $('.sidebar-toc .current a'); var $tocHeight = $('.sidebar-toc .toc').height();
if ($currLink[0] && $toc[0]) { if ($tocHeight <= $tocWrapperHeight) return;
var tocTop = $currLink.offset().top - $toc.offset().top;
isTocScroll = !!(tocTop > $toc.height() || tocTop < 0); var $tocWrapper = $('.sidebar-toc');
var $currTocItem = $('.sidebar-toc .current a');
if ($currTocItem[0] && $tocWrapper[0]) {
var tocTop = $currTocItem.offset().top - $tocWrapper.offset().top;
isTocScroll = tocTop > $tocWrapperHeight || tocTop < 0;
} }
if (isTocScroll) { if (isTocScroll) {
$currLink $currTocItem
.velocity('stop') .velocity('stop')
.velocity('scroll', { .velocity('scroll', {
container: $toc, container: $tocWrapper,
offset: -($toc.height() / 2), offset: (-$tocWrapperHeight / 2),
duration: 500, duration: 500,
easing: 'easeOutQuart' easing: 'easeOutQuart'
}); });
} }
} }
// Distance from sidebar to top.
var SIDEBAR_STICKY_TOP = parseInt(CONFIG.sidebar.offsetTop);
var isSidebarSticky = false;
// Sticky the sidebar when it arrived the top. // Sticky the sidebar when it arrived the top.
function sidebarSticky () { function sidebarSticky () {
var mainInner = $('.main-inner')[0]; var mainInner = $('.main-inner')[0];
...@@ -122,47 +97,16 @@ $(document).ready(function () { ...@@ -122,47 +97,16 @@ $(document).ready(function () {
var targetY = mainInner.getBoundingClientRect().top; var targetY = mainInner.getBoundingClientRect().top;
if (targetY < SIDEBAR_STICKY_TOP) { if (targetY < SIDEBAR_STICKY_TOP) {
$('.sidebar-inner').addClass('sticky'); if (!isSidebarSticky) {
} else { $('.sidebar-inner').addClass('sticky');
$('.sidebar-inner').removeClass('sticky'); isSidebarSticky = true;
}
}
}
// Auto adjust the height of sidebar when it arrive footer.
function sidebarAdjustHeight () {
var footerTop = $('#footer').offset().top;
var footerH = $('#footer')[0].getBoundingClientRect().height;
var sidebarTop = $('.sidebar-inner').offset().top;
var sidebarH = $('.sidebar-inner')[0].getBoundingClientRect().height;
if (!isAnime && sidebarTop + sidebarH > footerTop) {
var targetTocH =
parseInt($('.sidebar-toc').css('max-height')) - footerH;
isAnime = true;
$('.sidebar-toc').velocity({
maxHeight: targetTocH
}, {
duration: 300,
complete: function () {
isAnime = false;
isMaxH = false;
} }
}); } else {
} else if (!isMaxH && !isAnime && $(window).height() < if (isSidebarSticky) {
$('#footer')[0].getBoundingClientRect().top) { $('.sidebar-inner').removeClass('sticky');
isAnime = true; isSidebarSticky = false;
$('.sidebar-toc').velocity({
maxHeight: '70vh'
}, {
duration: 240,
complete: function () {
isAnime = false;
isMaxH = true;
} }
}); }
} }
} }
...@@ -175,9 +119,51 @@ $(document).ready(function () { ...@@ -175,9 +119,51 @@ $(document).ready(function () {
var percent = parseInt((scrollH / var percent = parseInt((scrollH /
Math.abs($post.height() - $(window).height())) * 100); Math.abs($post.height() - $(window).height())) * 100);
percent = percent > 100 ? 100 : percent < 0 ? 0 : percent; percent = percent > 100 ? 100 : percent < 0 ? 0 : percent;
percent += '%';
$('.sidebar-progress-number').html(percent); $('.sidebar-progress-number').html(percent);
$('.sidebar-progress-line').css('width', percent); $('.sidebar-progress-line').css(
'transform', 'translateX(' + (percent - 100) + '%)'
);
} }
// Initial run
autoSpreadToc();
sidebarSticky();
scrollTocToMiddle();
readProgress();
$(window).on('scroll', function () {
sidebarSticky();
});
$(window).on('scroll', Stun.utils.throttle(function () {
autoSpreadToc();
scrollTocToMiddle();
readProgress();
}, 150));
var $tocWrapper = $('.sidebar-toc');
var $view = $('.sidebar-overview');
$('.sidebar-nav-toc').on('click', function () {
$('.sidebar-nav-toc').toggleClass('current');
$('.sidebar-nav-overview').toggleClass('current');
$tocWrapper.css('display', 'block');
$tocWrapper.velocity('fadeIn');
$view.css('display', 'none');
$view.velocity('fadeOut');
});
$('.sidebar-nav-overview').on('click', function () {
$('.sidebar-nav-toc').toggleClass('current');
$('.sidebar-nav-overview').toggleClass('current');
$tocWrapper.css('display', 'none');
$tocWrapper.velocity('fadeOut');
$view.css('display', 'block');
$view.velocity('fadeIn');
});
}); });
$(document).ready(function () { $(document).ready(function () {
CONFIG.shortcuts.switch_post && Stun.utils.registerSwitchPost(); CONFIG.shortcuts.switch_post && Stun.utils.registerSwitchPost();
// Not reload this, because it's changeless.
if (CONFIG.external_link) {
Stun.utils.addIconToExternalLink('#footer');
}
Stun.utils.addCopyButtonToCopyright();
Stun.utils.registerCopyEvent();
CONFIG.reward && Stun.utils.registerShowReward(); CONFIG.reward && Stun.utils.registerShowReward();
CONFIG.back2top && Stun.utils.back2top();
CONFIG.gallery_waterfall && Stun.utils.galleryWaterFall(); CONFIG.gallery_waterfall && Stun.utils.galleryWaterFall();
CONFIG.lazyload && Stun.utils.lazyLoadImages(); CONFIG.lazyload && Stun.utils.lazyLoadImages();
if (CONFIG.external_link) { if (CONFIG.external_link) {
var WRAPPER = '.archive-inner, .post-title, #footer'; var WRAPPER = '.archive-inner, .post-title';
Stun.utils.addIconToExternalLink(WRAPPER); Stun.utils.addIconToExternalLink(WRAPPER);
} }
......
...@@ -66,6 +66,22 @@ Stun.utils = Stun.$u = { ...@@ -66,6 +66,22 @@ Stun.utils = Stun.$u = {
}; };
return throttled; return throttled;
}, },
hasMobileUA: function () {
var nav = window.navigator;
var ua = nav.userAgent;
var pa = /iPad|iPhone|Android|Opera Mini|BlackBerry|webOS|UCWEB|Blazer|PSP|IEMobile|Symbian/g;
return pa.test(ua);
},
isTablet: function () {
return window.screen.width > 767 && window.screen.width < 992 && this.hasMobileUA();
},
isMobile: function () {
return window.screen.width < 767 && this.hasMobileUA();
},
isDesktop: function () {
return !this.isTablet() && !this.isMobile();
},
/** /**
* Change the event code to keyCode. * Change the event code to keyCode.
* @param {String} code Event code * @param {String} code Event code
...@@ -188,6 +204,7 @@ Stun.utils = Stun.$u = { ...@@ -188,6 +204,7 @@ Stun.utils = Stun.$u = {
selector: '[data-fancybox]', selector: '[data-fancybox]',
loop: true, loop: true,
transitionEffect: 'slide', transitionEffect: 'slide',
hash: false,
buttons: [ buttons: [
'share', 'share',
'slideShow', 'slideShow',
...@@ -235,32 +252,6 @@ Stun.utils = Stun.$u = { ...@@ -235,32 +252,6 @@ Stun.utils = Stun.$u = {
.parent('.external-link') .parent('.external-link')
.append($icon); .append($icon);
}, },
// Back the page to top.
back2top: function () {
function back2topHandler () {
var $top = $('#back-top');
var scrollTop = $(window).scrollTop();
if (scrollTop !== 0) {
$top.css('visibility', 'visible');
} else {
$top.css('visibility', 'hidden');
}
}
$(window).on('load', back2topHandler);
$(window).on('scroll', back2topHandler);
$('#back-top').on('click', function () {
$('body').velocity('stop').velocity('scroll');
if (CONFIG.back2top.animation) {
$('#back-top')
.velocity({ translateY: '-100vh' }, { duration: 500 })
.velocity('reverse', { duration: 10 });
}
});
},
// Switch to the prev / next post by shortcuts. // Switch to the prev / next post by shortcuts.
registerSwitchPost: function () { registerSwitchPost: function () {
var _this = this; var _this = this;
...@@ -366,6 +357,58 @@ Stun.utils = Stun.$u = { ...@@ -366,6 +357,58 @@ Stun.utils = Stun.$u = {
}); });
} }
}, },
addCopyButtonToCopyright: function () {
$('figure.highlight').each(function () {
if (!$(this).find('figcaption')[0]) {
var CODEBLOCK_CLASS_NAME = 'highlight';
var lang = $(this)
.attr('class')
.split(/\s/)
.filter(function (e) { return e !== CODEBLOCK_CLASS_NAME; });
var $codeHeader = $(
'<figcaption class="custom">' +
'<div class="custom-lang">' + lang + '</div>' +
'</figcaption>'
);
$codeHeader.insertBefore($(this).children().first());
}
});
var $copyIcon = $(
'<div class="copy-button" data-popover=' +
CONFIG.prompt.copy_button +
' data-popover-pos="up">' +
'<i class="fa fa-clipboard"></i>' +
'</div>'
);
var COPY_BUTTON_CONTAINER =
'figure.highlight figcaption, .post-copyright';
// Add a copy button to the selected elements.
$(COPY_BUTTON_CONTAINER).append($copyIcon);
},
registerCopyEvent: function () {
$('.copy-button').on('click', function () {
var container = null;
// Select the container of code block.
var codeContainer =
$(this).parents('figure.highlight').find('td.code')[0];
if (codeContainer) {
container = codeContainer;
} else {
// Select the container of text.
container = $(this).parent()[0];
}
if (Stun.utils.copyText(container)) {
Stun.utils.popAlert('success', CONFIG.prompt.copy_success);
} else {
Stun.utils.popAlert('error', CONFIG.prompt.copy_error);
}
});
},
/** /**
* Wait for all images to load. * Wait for all images to load.
* @param {String} selector jQuery selector. * @param {String} selector jQuery selector.
...@@ -388,21 +431,5 @@ Stun.utils = Stun.$u = { ...@@ -388,21 +431,5 @@ Stun.utils = Stun.$u = {
imgDefereds.push(dfd); imgDefereds.push(dfd);
}); });
$.when.apply(null, imgDefereds).then(callback); $.when.apply(null, imgDefereds).then(callback);
},
hasMobileUA: function () {
var nav = window.navigator;
var ua = nav.userAgent;
var pa = /iPad|iPhone|Android|Opera Mini|BlackBerry|webOS|UCWEB|Blazer|PSP|IEMobile|Symbian/g;
return pa.test(ua);
},
isTablet: function () {
return window.screen.width > 767 && window.screen.width < 992 && this.hasMobileUA();
},
isMobile: function () {
return window.screen.width < 767 && this.hasMobileUA();
},
isDesktop: function () {
return !this.isTablet() && !this.isMobile();
} }
}; };
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册