Inhaltsverzeichnis
keine Gliederung:root {
/* Layout */
--tracker-width: 250px;
--tracker-bottom: 110px;
--tracker-left: 20px;
/* Typography */
--size-current: 22px;
--size-near: 16px;
--size-far: 14px;
/* Colors */
--color-current: #0066CC;
--color-near: #777777;
--color-far: #7777776b;
}
#trackerPageContent {
position: fixed;
bottom: var(--tracker-bottom);
left: var(--tracker-left);
width: var(--tracker-width);
z-index: 2147483000;
pointer-events: none;
opacity: 1;
transition: opacity 0.3s ease;
}
#trackerPageContent.hidden {
opacity: 0;
}
.tracker-list {
display: flex;
flex-direction: column;
gap: 6px;
}
.tracker-item {
line-height: 1.35;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
transition: all 0.25s ease;
}
.tracker-item.current {
font-size: var(--size-current);
font-weight: 600;
color: var(--color-current);
}
.tracker-item.near {
font-size: var(--size-near);
color: var(--color-near);
}
.tracker-item.far {
font-size: var(--size-far);
color: var(--color-far);
}
(function () {
'use strict';
var CONFIG = {
selectors : 'h1, h2, h3, h4',
threshold : 0.35,
throttle : 120,
range : 2,
excludeTexts : ['Von $1', 'Edit']
};
var panel = document.getElementById('trackerPageContent');
var list = document.getElementById('trackerList');
var content = document.querySelector('.content');
if (!panel || !list) return;
var headings = [];
var currentIndex = -1;
var timer;
function checkCollision() {
if (!content) {
panel.classList.remove('hidden');
return;
}
var panelRect = panel.getBoundingClientRect();
var contentRect = content.getBoundingClientRect();
var collision = !(
panelRect.right < contentRect.left ||
panelRect.left > contentRect.right ||
panelRect.bottom < contentRect.top ||
panelRect.top > contentRect.bottom
);
if (collision) {
panel.classList.add('hidden');
} else {
panel.classList.remove('hidden');
}
}
function collectHeadings() {
headings = Array.from(document.querySelectorAll(CONFIG.selectors))
.map(function (h) {
return {
el : h,
text : h.textContent.trim()
};
})
.filter(function (h) {
return !CONFIG.excludeTexts.includes(h.text);
});
}
function getTop(el) {
return el.getBoundingClientRect().top + window.pageYOffset;
}
function findCurrent() {
var pos = window.pageYOffset + window.innerHeight * CONFIG.threshold;
for (var i = headings.length - 1; i >= 0; i--) {
if (pos >= getTop(headings[i].el)) return i;
}
return 0;
}
function render() {
list.innerHTML = '';
if (!headings.length) return;
var start = Math.max(0, currentIndex - CONFIG.range);
var end = Math.min(headings.length - 1, currentIndex + CONFIG.range);
for (var i = start; i <= end; i++) {
var item = document.createElement('div');
item.className = 'tracker-item';
if (i === currentIndex) {
item.classList.add('current');
} else if (Math.abs(i - currentIndex) === 1) {
item.classList.add('near');
} else {
item.classList.add('far');
}
item.textContent = headings[i].text;
list.appendChild(item);
}
}
function update() {
if (!headings.length) return;
var idx = findCurrent();
if (idx === currentIndex) return;
currentIndex = idx;
render();
checkCollision();
}
window.addEventListener('scroll', function () {
clearTimeout(timer);
timer = setTimeout(function() {
update();
checkCollision();
}, CONFIG.throttle);
}, { passive: true });
window.addEventListener('resize', checkCollision);
function init(retry) {
collectHeadings();
if (!headings.length && retry < 10) {
setTimeout(function () { init(retry + 1); }, 300);
return;
}
update();
checkCollision();
}
init(0);
})();