Inhaltsverzeichnis
keine Gliederung
(function () {
console.log('=== TRACKER START ===');
if (document.getElementById('trackerPageContent')) {
console.log('ERROR: Tracker already exists!');
return;
}
var CONFIG = {
selectors: 'h2, h3, h4',
threshold: 0.35,
throttle: 80,
range: 2,
excludeTexts: ['Von $1', '*Edit'],
excludeContainers: ['.deki-page-titlex', '#siteSubx'],
bottomDefault: 110,
bottomMenuOpen: 300
};
// Create elements
var panel = document.createElement('div');
panel.id = 'trackerPageContent';
panel.style.cssText = 'position:fixed;bottom:110px;left:20px;width:250px;z-index:9999999;pointer-events:none;background:rgba(255,0,0,0.3);padding:10px;opacity:1';
var list = document.createElement('div');
list.id = 'trackerList';
list.style.cssText = 'display:flex;flex-direction:column;gap:6px';
panel.appendChild(list);
document.body.appendChild(panel);
console.log('✓ Panel created and added to body');
var headings = [];
var currentIndex = -1;
var timer;
function collectHeadings() {
console.log('--- Collecting headings ---');
var all = document.querySelectorAll(CONFIG.selectors);
console.log('Found ' + all.length + ' total headings');
var seenTexts = [];
headings = Array.from(all)
.filter(function (h) {
for (var i = 0; i < CONFIG.excludeContainers.length; i++) {
if (h.closest(CONFIG.excludeContainers[i])) return false;
}
return true;
})
.map(function (h) {
return { el: h, text: h.textContent.trim() };
})
.filter(function (h) {
for (var i = 0; i < CONFIG.excludeTexts.length; i++) {
var pattern = CONFIG.excludeTexts[i];
if (pattern.startsWith('*') && h.text.endsWith(pattern.substring(1))) return false;
if (pattern.endsWith('*') && h.text.startsWith(pattern.slice(0, -1))) return false;
if (h.text === pattern) return false;
}
if (seenTexts.includes(h.text)) return false;
seenTexts.push(h.text);
return true;
});
console.log('After filtering: ' + headings.length + ' headings');
headings.forEach(function(h, i) {
console.log(' [' + i + '] ' + h.text.substring(0, 40));
});
}
function getTop(el) {
var rect = el.getBoundingClientRect();
return rect.top + (window.pageYOffset || document.documentElement.scrollTop);
}
function findCurrent() {
if (!headings.length) return 0;
var scrollPos = window.pageYOffset || document.documentElement.scrollTop;
var triggerPoint = scrollPos + (window.innerHeight * CONFIG.threshold);
for (var i = headings.length - 1; i >= 0; i--) {
var top = getTop(headings[i].el);
if (triggerPoint >= top) {
return i;
}
}
return 0;
}
function render() {
console.log('RENDER at index: ' + currentIndex);
list.innerHTML = '';
if (!headings.length) {
list.innerHTML = '<div style="color:red">NO HEADINGS!</div>';
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.style.cssText = 'line-height:1.35;white-space:nowrap;overflow:hidden;text-overflow:ellipsis';
if (i === currentIndex) {
item.style.fontSize = '22px';
item.style.fontWeight = '600';
item.style.color = '#06C';
} else if (Math.abs(i - currentIndex) === 1) {
item.style.fontSize = '16px';
item.style.color = '#777';
} else {
item.style.fontSize = '14px';
item.style.color = '#999';
}
item.textContent = headings[i].text;
list.appendChild(item);
}
}
function update() {
if (!headings.length) return;
var idx = findCurrent();
if (idx !== currentIndex) {
currentIndex = idx;
render();
}
}
window.addEventListener('scroll', function () {
clearTimeout(timer);
timer = setTimeout(update, CONFIG.throttle);
}, { passive: true });
function init(attempt) {
console.log('INIT attempt #' + (attempt + 1));
collectHeadings();
if (headings.length > 0) {
console.log('✓ SUCCESS - found headings!');
currentIndex = findCurrent();
render();
return;
}
if (attempt < 30) {
console.log('No headings yet, retrying...');
setTimeout(function() {
init(attempt + 1);
}, 500);
} else {
console.log('✗ FAILED after 30 attempts');
list.innerHTML = '<div style="color:red">FAILED TO FIND HEADINGS</div>';
}
}
setTimeout(function() {
init(0);
}, 2000);
})();