update: perfect animation, compatibility issue
This commit is contained in:
parent
92840887d2
commit
cda49e0301
10 changed files with 134 additions and 87 deletions
|
@ -7,30 +7,31 @@
|
|||
return;
|
||||
}
|
||||
|
||||
var headerHeight = 0;
|
||||
var header = document.querySelector('header');
|
||||
if (header) {
|
||||
headerHeight = header.offsetHeight;
|
||||
}
|
||||
var supportPageOffset = window.pageXOffset !== undefined;
|
||||
var isCSS1Compat = ((document.compatMode || "") === "CSS1Compat");
|
||||
var scrollPos = getScrollPos();
|
||||
var offsetY = element.offsetTop - (header.offsetTop + header.offsetHeight + 20);
|
||||
|
||||
var x = supportPageOffset ? window.pageXOffset : isCSS1Compat ? document.documentElement.scrollLeft : document.body.scrollLeft;
|
||||
var y = supportPageOffset ? window.pageYOffset : isCSS1Compat ? document.documentElement.scrollTop : document.body.scrollTop;
|
||||
|
||||
var offsetY = element.offsetTop - headerHeight - 12;
|
||||
if (y === offsetY) {
|
||||
if (offsetY == scrollPos.y) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.scrollTo(x, offsetY);
|
||||
if (header.offsetTop == 0 && offsetY > scrollPos.y) {
|
||||
offsetY += header.offsetHeight;
|
||||
} else if (header.offsetTop < 0 && offsetY < scrollPos.y) {
|
||||
offsetY -= header.offsetHeight;
|
||||
}
|
||||
|
||||
smoothScrollTo(offsetY);
|
||||
}
|
||||
|
||||
// The first event occurred
|
||||
window.addEventListener('load', function(event) {
|
||||
if (window.location.hash) {
|
||||
hashLocate(window.location.hash);
|
||||
}
|
||||
});
|
||||
|
||||
// The first event occurred
|
||||
window.addEventListener('click', function(event) {
|
||||
if (event.target.matches('a')) {
|
||||
hashLocate(event.target.getAttribute('href'));
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
{%- seo -%}
|
||||
<link rel="shortcut icon" href="{{ site.favicon }}">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="{{ "/assets/main.css" | relative_url }}">
|
||||
<link rel="stylesheet" href="{{ "/assets/css/main.css" | relative_url }}">
|
||||
<script src="{{ "/assets/js/main.js" | relative_url }}"></script>
|
||||
{%- feed_meta -%}
|
||||
{%- if jekyll.environment == 'production' and site.google_analytics -%}
|
||||
{%- include extensions/google-analytics.html -%}
|
||||
|
|
|
@ -12,25 +12,23 @@
|
|||
</div>
|
||||
|
||||
<script>
|
||||
function generateContent() {
|
||||
var menu = document.querySelector(".post-menu .post-menu-content");
|
||||
var headings = document.querySelector(".post-content").querySelectorAll("h2, h3, h4, h5, h6");
|
||||
|
||||
// Generate post menu
|
||||
var menuHTML = '';
|
||||
headings.forEach(function (h) {
|
||||
for (var i = 0; i < headings.length; i++) {
|
||||
var h = headings[i];
|
||||
menuHTML += (
|
||||
'<li class="h-' + h.tagName.toLowerCase() + '">'
|
||||
+ '<a href="#h-' + h.getAttribute('id') + '">' + h.textContent + '</a></li>');
|
||||
});
|
||||
}
|
||||
|
||||
menu.innerHTML = '<ul>' + menuHTML + '</ul>';
|
||||
|
||||
// The anchor offsetHeight
|
||||
var headerHeight = 0;
|
||||
var header = document.querySelector('header');
|
||||
if (header) {
|
||||
offsetHeight = header.offsetHeight + 12;
|
||||
}
|
||||
// The header element
|
||||
var header = document.querySelector('header.site-header');
|
||||
|
||||
// Active the menu item
|
||||
window.addEventListener('scroll', function (event) {
|
||||
|
@ -39,7 +37,8 @@
|
|||
for (var i = headings.length - 1; i >= 0; i--) {
|
||||
var h = headings[i];
|
||||
var clientRect = h.getBoundingClientRect();
|
||||
if (clientRect.top < offsetHeight) {
|
||||
var headerHeight = header.offsetTop + header.offsetHeight + 20;
|
||||
if (clientRect.top <= headerHeight) {
|
||||
var id = 'h-' + h.getAttribute('id');
|
||||
var curActive = menu.querySelector('a[href="#' + id + '"]');
|
||||
if (curActive) {
|
||||
|
@ -56,4 +55,6 @@
|
|||
}
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
generateContent();
|
||||
</script>
|
||||
|
|
|
@ -62,21 +62,14 @@
|
|||
|
||||
<script>
|
||||
(function() {
|
||||
var supportPageOffset = window.pageXOffset !== undefined;
|
||||
var isCSS1Compat = ((document.compatMode || "") === "CSS1Compat");
|
||||
|
||||
function scrollY() {
|
||||
return supportPageOffset ? window.pageYOffset : isCSS1Compat ? document.documentElement.scrollTop : document.body.scrollTop;
|
||||
}
|
||||
|
||||
var lastScrollY = scrollY();
|
||||
var dataset = document.documentElement.dataset;
|
||||
var lastScrollY = getScrollPos().y;
|
||||
var documentElement = document.documentElement;
|
||||
|
||||
function storeScrollData() {
|
||||
var y = scrollY();
|
||||
var y = getScrollPos().y;
|
||||
|
||||
{%- if banner and header_transparent -%}
|
||||
dataset.headerTransparent = "";
|
||||
documentElement.setAttribute("data-header-transparent", "");
|
||||
{%- endif -%}
|
||||
|
||||
var scrollStatus = "";
|
||||
|
@ -91,7 +84,7 @@
|
|||
}
|
||||
|
||||
lastScrollY = y;
|
||||
dataset.scrollStatus = scrollStatus;
|
||||
documentElement.setAttribute("data-scroll-status", scrollStatus);
|
||||
}
|
||||
|
||||
window.addEventListener('scroll', function(e) {
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
}
|
||||
|
||||
li {
|
||||
border-bottom: 1px solid $background-color;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
|
|
@ -122,15 +122,19 @@ body {
|
|||
position: absolute;
|
||||
top: 110%;
|
||||
right: -10px;
|
||||
background-color: lighten($theme-color, 5%);
|
||||
-webkit-transition: all 0.25s ease-in-out;
|
||||
transition: all 0.25s ease-in-out;
|
||||
width: 100px;
|
||||
text-align: center;
|
||||
padding-top: 0;
|
||||
margin-top: 0;
|
||||
z-index: 200;
|
||||
border-radius: 3px;
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
visibility: hidden;
|
||||
|
||||
li {
|
||||
background: lighten($theme-color, 5%);
|
||||
padding: 5px;
|
||||
|
||||
a {
|
||||
|
@ -140,24 +144,14 @@ body {
|
|||
img {
|
||||
width: 24px;
|
||||
max-height: 24px;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
padding-top: 10px;
|
||||
border-radius: 3px 3px 0 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
padding-bottom: 10px;
|
||||
border-radius: 0 0 3px 3px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@extend .ct-language-selected;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.list-unstyled {
|
||||
|
@ -169,7 +163,7 @@ body {
|
|||
.ct-language {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
background: #fefefe2b;
|
||||
background-color: #fefefe2b;
|
||||
padding: 3px 10px;
|
||||
border-radius: 3px;
|
||||
|
||||
|
@ -177,8 +171,9 @@ body {
|
|||
cursor: pointer;
|
||||
|
||||
.ct-language-dropdown {
|
||||
padding-top: 8px;
|
||||
margin-top: 8px;
|
||||
max-height: 10000px;
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -229,7 +229,7 @@ table {
|
|||
/**
|
||||
* Flex layout
|
||||
*/
|
||||
%flex-layout {
|
||||
%flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
|
|
|
@ -200,6 +200,7 @@ html {
|
|||
*/
|
||||
.page-content {
|
||||
@extend %flex-1; /* <-- Keep footer on the bottom */
|
||||
-ms-flex: none; /* <-- Fix IE footer issue */
|
||||
padding: $spacing-unit * 1.5 0;
|
||||
}
|
||||
|
||||
|
@ -378,7 +379,7 @@ html {
|
|||
* Layout and sidebar
|
||||
*/
|
||||
.framework {
|
||||
@extend %flex-layout;
|
||||
@extend %flex;
|
||||
|
||||
.main {
|
||||
@extend %flex-1;
|
||||
|
|
57
assets/js/main.js
Normal file
57
assets/js/main.js
Normal file
|
@ -0,0 +1,57 @@
|
|||
// Fix DOM matches function
|
||||
if (!Element.prototype.matches) {
|
||||
Element.prototype.matches =
|
||||
Element.prototype.matchesSelector ||
|
||||
Element.prototype.mozMatchesSelector ||
|
||||
Element.prototype.msMatchesSelector ||
|
||||
Element.prototype.oMatchesSelector ||
|
||||
Element.prototype.webkitMatchesSelector ||
|
||||
function(s) {
|
||||
var matches = (this.document || this.ownerDocument).querySelectorAll(s),
|
||||
i = matches.length;
|
||||
while (--i >= 0 && matches.item(i) !== this) {}
|
||||
return i > -1;
|
||||
};
|
||||
}
|
||||
|
||||
// Get Scroll position
|
||||
function getScrollPos() {
|
||||
var supportPageOffset = window.pageXOffset !== undefined;
|
||||
var isCSS1Compat = ((document.compatMode || "") === "CSS1Compat");
|
||||
|
||||
var x = supportPageOffset ? window.pageXOffset : isCSS1Compat ? document.documentElement.scrollLeft : document.body.scrollLeft;
|
||||
var y = supportPageOffset ? window.pageYOffset : isCSS1Compat ? document.documentElement.scrollTop : document.body.scrollTop;
|
||||
|
||||
return { x: x, y: y };
|
||||
}
|
||||
|
||||
var _scrollTimer = [];
|
||||
|
||||
// Smooth scroll
|
||||
function smoothScrollTo(y, time) {
|
||||
time = time == undefined ? 500 : time;
|
||||
|
||||
var scrollPos = getScrollPos();
|
||||
var count = 60;
|
||||
var length = (y - scrollPos.y);
|
||||
|
||||
function easeInOut(k) {
|
||||
return .5 * (Math.sin((k - .5) * Math.PI) + 1);
|
||||
}
|
||||
|
||||
for (var i = _scrollTimer.length - 1; i >= 0; i--) {
|
||||
clearTimeout(_scrollTimer[i]);
|
||||
}
|
||||
|
||||
for (var i = 0; i <= count; i++) {
|
||||
(function() {
|
||||
var cur = i;
|
||||
_scrollTimer[cur] = setTimeout(function() {
|
||||
window.scrollTo(
|
||||
scrollPos.x,
|
||||
scrollPos.y + length * easeInOut(cur/count)
|
||||
);
|
||||
}, (time / count) * cur);
|
||||
})();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue