mirror of
https://github.com/next-theme/hexo-theme-next.git
synced 2026-01-20 19:02:33 +00:00
Use position: sticky
This commit is contained in:
parent
b01a4ed7d7
commit
b9968b6be0
@ -1 +0,0 @@
|
|||||||
{{- next_js('schemes/pisces.js') }}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
{{- next_js('schemes/pisces.js') }}
|
|
||||||
@ -51,6 +51,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.content-wrap {
|
.content-wrap {
|
||||||
|
align-self: stretch;
|
||||||
background: var(--content-bg-color);
|
background: var(--content-bg-color);
|
||||||
border-radius: $border-radius-inner;
|
border-radius: $border-radius-inner;
|
||||||
box-shadow: $box-shadow-inner;
|
box-shadow: $box-shadow-inner;
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
.sidebar {
|
.sidebar {
|
||||||
background: var(--body-bg-color);
|
// Make sure that .content-wrap and .sidebar are the same height
|
||||||
|
// Required for .sidebar-inner `position: sticky;`
|
||||||
|
align-self: stretch;
|
||||||
|
background: initial;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
margin-top: 100%;
|
|
||||||
position: static;
|
position: static;
|
||||||
width: $sidebar-desktop;
|
width: $sidebar-desktop;
|
||||||
|
|
||||||
@ -20,20 +22,13 @@
|
|||||||
box-shadow: $box-shadow;
|
box-shadow: $box-shadow;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
|
position: sticky;
|
||||||
|
top: $sidebar-offset;
|
||||||
width: $sidebar-desktop;
|
width: $sidebar-desktop;
|
||||||
|
|
||||||
if (hexo-config('motion.enable') && hexo-config('motion.transition.sidebar')) {
|
if (hexo-config('motion.enable') && hexo-config('motion.transition.sidebar')) {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.affix {
|
|
||||||
position: fixed;
|
|
||||||
top: $sidebar-offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.affix-bottom {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-state-item a {
|
.site-state-item a {
|
||||||
|
|||||||
@ -71,6 +71,15 @@ NexT.boot.registerEvents = function() {
|
|||||||
target && target.click();
|
target && target.click();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (CONFIG.scheme === 'Pisces' || CONFIG.scheme === 'Gemini') {
|
||||||
|
NexT.utils.setAffixParam();
|
||||||
|
window.matchMedia('(min-width: 992px)').addListener(event => {
|
||||||
|
if (event.matches) {
|
||||||
|
NexT.utils.setAffixParam();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
NexT.boot.refresh = function() {
|
NexT.boot.refresh = function() {
|
||||||
|
|||||||
@ -1,86 +0,0 @@
|
|||||||
/* global NexT, CONFIG */
|
|
||||||
|
|
||||||
const Affix = {
|
|
||||||
init: function(element, options) {
|
|
||||||
this.element = element;
|
|
||||||
this.offset = options || 0;
|
|
||||||
this.affixed = null;
|
|
||||||
this.unpin = null;
|
|
||||||
this.pinnedOffset = null;
|
|
||||||
this.checkPosition();
|
|
||||||
window.addEventListener('scroll', this.checkPosition.bind(this));
|
|
||||||
window.addEventListener('click', this.checkPositionWithEventLoop.bind(this));
|
|
||||||
window.matchMedia('(min-width: 992px)').addListener(event => {
|
|
||||||
if (event.matches) {
|
|
||||||
this.offset = NexT.utils.getAffixParam();
|
|
||||||
this.checkPosition();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getState: function(scrollHeight, height, offsetTop, offsetBottom) {
|
|
||||||
let scrollTop = window.scrollY;
|
|
||||||
let targetHeight = window.innerHeight;
|
|
||||||
if (offsetTop != null && this.affixed === 'top') {
|
|
||||||
if (document.querySelector('.content-wrap').offsetHeight < offsetTop) return 'top';
|
|
||||||
return scrollTop < offsetTop ? 'top' : false;
|
|
||||||
}
|
|
||||||
if (this.affixed === 'bottom') {
|
|
||||||
if (offsetTop != null) return this.unpin <= this.element.getBoundingClientRect().top ? false : 'bottom';
|
|
||||||
return scrollTop + targetHeight <= scrollHeight - offsetBottom ? false : 'bottom';
|
|
||||||
}
|
|
||||||
let initializing = this.affixed === null;
|
|
||||||
let colliderTop = initializing ? scrollTop : this.element.getBoundingClientRect().top + scrollTop;
|
|
||||||
let colliderHeight = initializing ? targetHeight : height;
|
|
||||||
if (offsetTop != null && scrollTop <= offsetTop) return 'top';
|
|
||||||
if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom';
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
getPinnedOffset: function() {
|
|
||||||
if (this.pinnedOffset) return this.pinnedOffset;
|
|
||||||
this.element.classList.remove('affix-top', 'affix-bottom');
|
|
||||||
this.element.classList.add('affix');
|
|
||||||
return (this.pinnedOffset = this.element.getBoundingClientRect().top);
|
|
||||||
},
|
|
||||||
checkPositionWithEventLoop() {
|
|
||||||
setTimeout(this.checkPosition.bind(this), 1);
|
|
||||||
},
|
|
||||||
checkPosition: function() {
|
|
||||||
if (window.getComputedStyle(this.element).display === 'none') return;
|
|
||||||
let height = this.element.offsetHeight;
|
|
||||||
let { offset } = this;
|
|
||||||
let offsetTop = offset.top;
|
|
||||||
let offsetBottom = offset.bottom;
|
|
||||||
let { scrollHeight } = document.body;
|
|
||||||
let affix = this.getState(scrollHeight, height, offsetTop, offsetBottom);
|
|
||||||
if (this.affixed !== affix) {
|
|
||||||
if (this.unpin != null) this.element.style.top = '';
|
|
||||||
let affixType = 'affix' + (affix ? '-' + affix : '');
|
|
||||||
this.affixed = affix;
|
|
||||||
this.unpin = affix === 'bottom' ? this.getPinnedOffset() : null;
|
|
||||||
this.element.classList.remove('affix', 'affix-top', 'affix-bottom');
|
|
||||||
this.element.classList.add(affixType);
|
|
||||||
}
|
|
||||||
if (affix === 'bottom') {
|
|
||||||
this.element.style.top = scrollHeight - height - offsetBottom + 'px';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
NexT.utils.getAffixParam = function() {
|
|
||||||
const sidebarOffset = CONFIG.sidebar.offset || 12;
|
|
||||||
|
|
||||||
let headerOffset = document.querySelector('.header-inner').offsetHeight;
|
|
||||||
let footerOffset = document.querySelector('.footer').offsetHeight;
|
|
||||||
|
|
||||||
document.querySelector('.sidebar').style.marginTop = headerOffset + sidebarOffset + 'px';
|
|
||||||
|
|
||||||
return {
|
|
||||||
top : headerOffset,
|
|
||||||
bottom: footerOffset
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
|
|
||||||
Affix.init(document.querySelector('.sidebar-inner'), NexT.utils.getAffixParam());
|
|
||||||
});
|
|
||||||
@ -362,6 +362,13 @@ NexT.utils = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setAffixParam: function() {
|
||||||
|
const sidebarOffset = CONFIG.sidebar.offset || 12;
|
||||||
|
const headerOffset = document.querySelector('.header-inner').offsetHeight;
|
||||||
|
|
||||||
|
document.querySelector('.sidebar-inner').style.marginTop = headerOffset + sidebarOffset + 'px';
|
||||||
|
},
|
||||||
|
|
||||||
getScript: function(url, callback, condition) {
|
getScript: function(url, callback, condition) {
|
||||||
if (condition) {
|
if (condition) {
|
||||||
callback();
|
callback();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user