From 3a19c7229c07e4de07453d8a23775f6dee1a687f Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Tue, 10 Apr 2018 19:19:37 +0300 Subject: www: hide header on scroll --- juick-www/src/main/assets/scripts.js | 114 +++++++++++++++++++++++++++-------- juick-www/src/main/assets/style.css | 11 ++++ 2 files changed, 99 insertions(+), 26 deletions(-) (limited to 'juick-www/src/main/assets') diff --git a/juick-www/src/main/assets/scripts.js b/juick-www/src/main/assets/scripts.js index 57ab9ee4..d168911a 100644 --- a/juick-www/src/main/assets/scripts.js +++ b/juick-www/src/main/assets/scripts.js @@ -6,7 +6,7 @@ let Awesomplete = require('awesomplete'); import * as killy from './embed'; if (!('remove' in Element.prototype)) { // Firefox <23 - Element.prototype.remove = function() { + Element.prototype.remove = function () { if (this.parentNode) { this.parentNode.removeChild(this); } @@ -39,7 +39,7 @@ function autosize(el) { ? (el.offsetHeight - el.clientHeight) : (el.offsetHeight + parseInt(window.getComputedStyle(el, null).getPropertyValue('border-top-width'))); - let resize = function(el) { + let resize = function (el) { el.style.height = 'auto'; el.style.height = (el.scrollHeight + offset) + 'px'; }; @@ -113,7 +113,7 @@ function getLang() { || window.navigator.userLanguage || window.navigator.language; } -function i18n(key, lang=undefined) { +function i18n(key, lang = undefined) { const fallbackLang = 'ru'; lang = lang || getLang().split('-')[0]; return (translations[lang] && translations[lang][key]) @@ -289,8 +289,8 @@ function newMessage(evt) { t.remove(); }); if (document.querySelector('#newmessage textarea').value.length == 0 - && document.querySelector('#newmessage .img').value.length == 0 - && !document.querySelector('#newmessage input[type="file"]')) { + && document.querySelector('#newmessage .img').value.length == 0 + && !document.querySelector('#newmessage input[type="file"]')) { document.querySelector('#newmessage').insertAdjacentHTML('afterbegin', `

${i18n('postForm.pleaseInputMessageText')}

`); evt.preventDefault(); } @@ -520,10 +520,10 @@ function resultMessage(str) { function likeMessage(e, mid) { if (confirm(i18n('message.likeThisMessage?'))) { fetch('//api.juick.com/like?mid=' + mid - + '&hash=' + document.getElementById('body').getAttribute('data-hash'), { - method: 'POST', - credentials: 'same-origin' - }) + + '&hash=' + document.getElementById('body').getAttribute('data-hash'), { + method: 'POST', + credentials: 'same-origin' + }) .then(function (response) { if (response.ok) { e.closest('article').appendChild(resultMessage('OK!')); @@ -563,22 +563,22 @@ function setPrivacy(e, mid) { function getTags() { fetch('//api.juick.com/tags?hash=' + document.getElementById('body').getAttribute('data-hash'), { - credentials: 'same-origin' - }) - .then(response => { - return response.json(); - }) - .then(json => { - let tags = json.map(t => t.tag); - let input = document.getElementById('tags_input'); - new Awesomplete(input, {list : tags}); - }); - return false; + credentials: 'same-origin' + }) + .then(response => { + return response.json(); + }) + .then(json => { + let tags = json.map(t => t.tag); + let input = document.getElementById('tags_input'); + new Awesomplete(input, { list: tags }); + }); + return false; } function addTag(tag) { - document.forms['postmsg'].body.value='*'+tag+' '+document.forms['postmsg'].body.value; - return false; + document.forms['postmsg'].body.value = '*' + tag + ' ' + document.forms['postmsg'].body.value; + return false; } /******************************************************************************/ @@ -609,10 +609,10 @@ ready(function () { }); }); document.querySelectorAll('#postmsg textarea').forEach(function (e) { - e.addEventListener('keypress', function (e) { - postformListener(e.target, e); - }); + e.addEventListener('keypress', function (e) { + postformListener(e.target, e); }); + }); var content = document.getElementById('content'); if (content) { @@ -643,7 +643,7 @@ ready(function () { var postmsg = document.getElementById('postmsg'); if (postmsg) { - document.querySelectorAll('a').filter(t => t.href.indexOf('?') >=0).forEach(t => { + document.querySelectorAll('a').filter(t => t.href.indexOf('?') >= 0).forEach(t => { t.addEventListener('click', e => { let params = new URLSearchParams(t.href.slice(t.href.indexOf('?') + 1)); if (params.has('tag')) { @@ -734,4 +734,66 @@ ready(function () { window.addEventListener('pagehide', wsShutdown); killy.embedAll(); + var elSelector = 'header', + elClassHidden = 'header--hidden', + throttleTimeout = 500, + element = document.querySelector(elSelector); + + if (element) { + + var dHeight = 0, + wHeight = 0, + wScrollCurrent = 0, + wScrollBefore = 0, + wScrollDiff = 0, + + hasElementClass = function (element, className) { return element.classList ? element.classList.contains(className) : new RegExp('(^| )' + className + '( |$)', 'gi').test(element.className); }, + addElementClass = function (element, className) { element.classList ? element.classList.add(className) : element.className += ' ' + className; }, + removeElementClass = function (element, className) { element.classList ? element.classList.remove(className) : element.className = element.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); }, + + throttle = function (delay, fn) { + var last, deferTimer; + return function () { + var context = this, args = arguments, now = +new Date; + if (last && now < last + delay) { + clearTimeout(deferTimer); + deferTimer = setTimeout( + function () { + last = now; + fn.apply(context, args); + }, + delay); + } else { + last = now; + fn.apply(context, args); + } + }; + }; + + window.addEventListener('scroll', throttle(throttleTimeout, function () { + dHeight = document.body.offsetHeight; + wHeight = window.innerHeight; + wScrollCurrent = window.pageYOffset; + wScrollDiff = wScrollBefore - wScrollCurrent; + + if (wScrollCurrent <= 0) { + // scrolled to the very top; element sticks to the top + removeElementClass(element, elClassHidden); + } else if (wScrollDiff > 0 && hasElementClass(element, elClassHidden)) { + // scrolled up; element slides in + removeElementClass(element, elClassHidden); + } else if (wScrollDiff < 0) { + // scrolled down + if (wScrollCurrent + wHeight >= dHeight && hasElementClass(element, elClassHidden)) { + // scrolled to the very bottom; element slides in + removeElementClass(element, elClassHidden); + } else { + // scrolled down; element slides out + addElementClass(element, elClassHidden); + } + } + + wScrollBefore = wScrollCurrent; + })); + } }); diff --git a/juick-www/src/main/assets/style.css b/juick-www/src/main/assets/style.css index 364cd7ef..d2cb984f 100644 --- a/juick-www/src/main/assets/style.css +++ b/juick-www/src/main/assets/style.css @@ -98,6 +98,12 @@ body > header { top: 0; width: 100%; z-index: 10; + -webkit-transition-duration: 0.5s; + transition-duration: 0.5s; + -webkit-transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + -webkit-transition-property: -webkit-transform; + transition-property: transform; } #header_wrapper { margin: 0 auto; @@ -108,6 +114,11 @@ body > header { flex-wrap: wrap; padding: 4px; } +.header--hidden { + -webkit-transform: translateY(-100%); + -ms-transform: translateY(-100%); + transform: translateY(-100%); +} #footer { clear: both; color: #999; -- cgit v1.2.3