54 lines
1.8 KiB
JavaScript
54 lines
1.8 KiB
JavaScript
// #267: jump to top / bottom for long content.
|
|
// Works on the paste view (page scroll) and the /new editor (textarea scroll).
|
|
// Buttons only appear when the content is tall enough to need them.
|
|
(function () {
|
|
const nav = document.querySelector('.jump-nav');
|
|
if (!nav) return;
|
|
const topBtn = nav.querySelector('.jump-top');
|
|
const botBtn = nav.querySelector('.jump-bottom');
|
|
|
|
// Target: the editor textarea on /new, else the window (paste view).
|
|
const editor = document.getElementById('content');
|
|
const target = editor || window;
|
|
|
|
function metrics() {
|
|
if (editor) {
|
|
return {
|
|
top: editor.scrollTop,
|
|
max: editor.scrollHeight - editor.clientHeight,
|
|
view: editor.clientHeight
|
|
};
|
|
}
|
|
const doc = document.documentElement;
|
|
return {
|
|
top: window.scrollY,
|
|
max: doc.scrollHeight - window.innerHeight,
|
|
view: window.innerHeight
|
|
};
|
|
}
|
|
|
|
function refresh() {
|
|
const m = metrics();
|
|
const tall = m.max > m.view * 1.5;
|
|
nav.classList.toggle('show', tall);
|
|
if (!tall) return;
|
|
// Hide the button for the edge you are already at.
|
|
topBtn.classList.toggle('hidden', m.top < 8);
|
|
botBtn.classList.toggle('hidden', m.max - m.top < 8);
|
|
}
|
|
|
|
function jump(toTop) {
|
|
const y = toTop ? 0 : 99999999;
|
|
if (editor) editor.scrollTo({ top: toTop ? 0 : editor.scrollHeight, behavior: 'smooth' });
|
|
else window.scrollTo({ top: toTop ? 0 : document.documentElement.scrollHeight, behavior: 'smooth' });
|
|
}
|
|
|
|
topBtn.addEventListener('click', () => jump(true));
|
|
botBtn.addEventListener('click', () => jump(false));
|
|
|
|
target.addEventListener('scroll', refresh, { passive: true });
|
|
if (editor) editor.addEventListener('input', refresh);
|
|
window.addEventListener('resize', refresh);
|
|
refresh();
|
|
})();
|