diff options
author | Jeffrey Tse <jeffreytse.mail@gmail.com> | 2019-09-24 14:10:57 +0800 |
---|---|---|
committer | Jeffrey Tse <jeffreytse.mail@gmail.com> | 2019-09-24 14:10:57 +0800 |
commit | cda49e03018d3dbbe8b9dc3927719471150c1608 (patch) | |
tree | a94523d13898c106c90e4d9285cf6136d45b7a33 | |
parent | 92840887d2591d8ba9b92074e193ef1a922c118d (diff) |
update: perfect animation, compatibility issue
-rw-r--r-- | _includes/extensions/hashlocate.html | 31 | ||||
-rw-r--r-- | _includes/head.html | 3 | ||||
-rw-r--r-- | _includes/sidebar/article-menu.html | 77 | ||||
-rw-r--r-- | _includes/views/header.html | 17 | ||||
-rw-r--r-- | _sass/misc/common-list.scss | 2 | ||||
-rw-r--r-- | _sass/misc/google-translate.scss | 25 | ||||
-rw-r--r-- | _sass/yat/_base.scss | 2 | ||||
-rw-r--r-- | _sass/yat/_layout.scss | 3 | ||||
-rw-r--r-- | assets/css/main.scss (renamed from assets/main.scss) | 0 | ||||
-rw-r--r-- | assets/js/main.js | 57 |
10 files changed, 132 insertions, 85 deletions
diff --git a/_includes/extensions/hashlocate.html b/_includes/extensions/hashlocate.html index d44b249..6faf553 100644 --- a/_includes/extensions/hashlocate.html +++ b/_includes/extensions/hashlocate.html @@ -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 x = supportPageOffset ? window.pageXOffset : isCSS1Compat ? document.documentElement.scrollLeft : document.body.scrollLeft; - var y = supportPageOffset ? window.pageYOffset : isCSS1Compat ? document.documentElement.scrollTop : document.body.scrollTop; + var scrollPos = getScrollPos(); + var offsetY = element.offsetTop - (header.offsetTop + header.offsetHeight + 20); - 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 - if (window.location.hash) { - hashLocate(window.location.hash); - } + 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')); diff --git a/_includes/head.html b/_includes/head.html index 770a7bf..be3be7a 100644 --- a/_includes/head.html +++ b/_includes/head.html @@ -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 -%} diff --git a/_includes/sidebar/article-menu.html b/_includes/sidebar/article-menu.html index aa4184d..7f83160 100644 --- a/_includes/sidebar/article-menu.html +++ b/_includes/sidebar/article-menu.html @@ -12,48 +12,49 @@ </div> <script> - var menu = document.querySelector(".post-menu .post-menu-content"); - var headings = document.querySelector(".post-content").querySelectorAll("h2, h3, h4, h5, h6"); + 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) { - menuHTML += ( - '<li class="h-' + h.tagName.toLowerCase() + '">' - + '<a href="#h-' + h.getAttribute('id') + '">' + h.textContent + '</a></li>'); - }); + // Generate post menu + var menuHTML = ''; + 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>'; + 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) { - var lastActive = menu.querySelector('.active'); - var changed = true; - for (var i = headings.length - 1; i >= 0; i--) { - var h = headings[i]; - var clientRect = h.getBoundingClientRect(); - if (clientRect.top < offsetHeight) { - var id = 'h-' + h.getAttribute('id'); - var curActive = menu.querySelector('a[href="#' + id + '"]'); - if (curActive) { - curActive.classList.add('active'); - } - if (lastActive == curActive) { - changed = false; + // Active the menu item + window.addEventListener('scroll', function (event) { + var lastActive = menu.querySelector('.active'); + var changed = true; + for (var i = headings.length - 1; i >= 0; i--) { + var h = headings[i]; + var clientRect = h.getBoundingClientRect(); + 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) { + curActive.classList.add('active'); + } + if (lastActive == curActive) { + changed = false; + } + break; } - break; } - } - if (lastActive && changed) { - lastActive.classList.remove('active'); - } - event.preventDefault(); - }); + if (lastActive && changed) { + lastActive.classList.remove('active'); + } + event.preventDefault(); + }); + } + generateContent(); </script> diff --git a/_includes/views/header.html b/_includes/views/header.html index 835d4cb..f23401f 100644 --- a/_includes/views/header.html +++ b/_includes/views/header.html @@ -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) { diff --git a/_sass/misc/common-list.scss b/_sass/misc/common-list.scss index 97f7b31..54b7165 100644 --- a/_sass/misc/common-list.scss +++ b/_sass/misc/common-list.scss @@ -15,8 +15,6 @@ } li { - border-bottom: 1px solid $background-color; - &:last-child { border-bottom: none; } diff --git a/_sass/misc/google-translate.scss b/_sass/misc/google-translate.scss index d2cae1a..243da54 100644 --- a/_sass/misc/google-translate.scss +++ b/_sass/misc/google-translate.scss @@ -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; } } diff --git a/_sass/yat/_base.scss b/_sass/yat/_base.scss index e92c561..01b8d1a 100644 --- a/_sass/yat/_base.scss +++ b/_sass/yat/_base.scss @@ -229,7 +229,7 @@ table { /** * Flex layout */ -%flex-layout { +%flex { display: flex; } diff --git a/_sass/yat/_layout.scss b/_sass/yat/_layout.scss index e4960f1..50bbb13 100644 --- a/_sass/yat/_layout.scss +++ b/_sass/yat/_layout.scss @@ -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; diff --git a/assets/main.scss b/assets/css/main.scss index 112a9ef..112a9ef 100644 --- a/assets/main.scss +++ b/assets/css/main.scss diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100644 index 0000000..231191b --- /dev/null +++ b/assets/js/main.js @@ -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); + })(); + } +} |