1/* Bauimpulse Blog: Floating Section-Headlines. 2 Die Headline (.mm-sticky-head) sitzt immer in der Luecke oberhalb der 3 aktuell sichtbaren Grund-Box (ul.mm-reasons li) innerhalb ihrer .mm-section. 4 Positionierung erfolgt SOFORT und ohne Animation -> keine Zwischenzustaende, 5 robust bei schnellem Scrollen. */ 6(function () { 7 'use strict'; 8 9 var data = Array.prototype.slice.call(document.querySelectorAll('.mm-section')).map(function (sec) { 10 return { 11 head: sec.querySelector('.mm-sticky-head'), 12 items: Array.prototype.slice.call(sec.querySelectorAll('ul.mm-reasons li')), 13 current: null 14 }; 15 }).filter(function (d) { 16 return d.head && d.items.length; 17 }); 18 19 if (!data.length) return; 20 21 var GAP = 10; // px Abstand Label-Unterkante -> Box-Oberkante 22 var TRIGGER = 0.35; // Box gilt als aktuell, sobald ihre Oberkante ueber 35% Viewport-Hoehe steigt 23 var ticking = false; 24 25 function marginOf(li) { 26 return parseFloat(li.style.marginTop) || 0; 27 } 28 29 // Top-Position von li OHNE die gesetzten Luecken-Margins (natuerliches Layout) 30 function naturalTop(d, li) { 31 var t = li.offsetTop - marginOf(li); 32 if (d.current && d.current !== li) { 33 var prevIdx = d.items.indexOf(d.current); 34 var thisIdx = d.items.indexOf(li); 35 if (prevIdx >= 0 && prevIdx < thisIdx) t -= marginOf(d.current); 36 } 37 return t; 38 } 39 40 function applyPosition(d, current) { 41 var headH = d.head.offsetHeight; 42 var M = headH + GAP; 43 var target = naturalTop(d, current); 44 d.items.forEach(function (li) { 45 li.style.marginTop = (li === current ? M : 0) + 'px'; 46 }); 47 d.head.style.transform = 'translateY(' + Math.max(0, Math.round(target)) + 'px)'; 48 d.current = current; 49 } 50 51 function update() { 52 ticking = false; 53 var triggerY = window.innerHeight * TRIGGER; 54 data.forEach(function (d) { 55 var current = d.items[0]; 56 d.items.forEach(function (li) { 57 if (li.getBoundingClientRect().top <= triggerY) current = li; 58 }); 59 if (current !== d.current) applyPosition(d, current); 60 }); 61 } 62 63 function onScroll() { 64 if (!ticking) { 65 ticking = true; 66 window.requestAnimationFrame(update); 67 } 68 } 69 70 function onResize() { 71 data.forEach(function (d) { 72 if (d.current) applyPosition(d, d.current); 73 }); 74 } 75 76 window.addEventListener('scroll', onScroll, { passive: true }); 77 window.addEventListener('resize', onResize); 78 update(); 79 80 // Nach Webfont-Load kann sich die Label-Hoehe aendern -> Luecken neu messen 81 if (document.fonts && document.fonts.ready) { 82 document.fonts.ready.then(onResize); 83 } 84})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.