https://www.lawsociety.ie/UI/js/Blocks/ticker-block.js?v=RZLWQprDdIdnNhNr2bBl-vyerF1oIpfvqQG68QdCCHM
1// Step-by-step ticker (one item at a time) 2(function () { 3 function initStepTicker(container) { 4 if (!container || container.__tickerInited) return; 5 container.__tickerInited = true; 6 7 var viewport = container.querySelector('.ticker__viewport'); 8 var track = container.querySelector('.ticker__track'); 9 if (!viewport || !track) return; 10 11 var items = Array.prototype.slice.call(track.querySelectorAll('.ticker__item')); 12 if (!items.length) return; 13 14 var pauseMs = parseInt(container.getAttribute('data-pause-ms') || '3000', 10); 15 var pps = parseFloat(container.getAttribute('data-speed-pps') || '120'); 16 if (isNaN(pps) || pps <= 0) pps = 120; 17 18 var respectRMAttr = (container.getAttribute('data-respect-rm') || 'false').toLowerCase(); 19 var respectRM = respectRMAttr === 'true'; 20 21 var prefersReduced = false; 22 try { prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches; } catch (e) { } 23 var autoRun = !(respectRM && prefersReduced); 24 25 // If only one item, just show it statically 26 if (items.length === 1) { 27 items[0].classList.add('ticker__item--active'); 28 items[0].style.opacity = '1'; 29 items[0].style.visibility = 'visible'; 30 return; 31 } 32 33 var currentIndex = 0; 34 var pausedByUser = false; 35 var timerId = null; 36 var isAnimating = false; 37 38 // Function to show a specific item 39 function showItem(index) { 40 if (isAnimating) return; 41 42 // Hide all items 43 items.forEach(function (item) { 44 item.classList.remove('ticker__item--active'); 45 item.style.opacity = '0'; 46 item.style.visibility = 'hidden'; 47 }); 48 49 // Show the current item 50 if (items[index]) { 51 items[index].classList.add('ticker__item--active'); 52 items[index].style.opacity = '1'; 53 items[index].style.visibility = 'visible'; 54 } 55 56 currentIndex = index; 57 } 58 59 // Function to transition to next item with fade effect 60 function transitionToNext() { 61 if (isAnimating) return; 62 63 isAnimating = true; 64 65 // Start fade out 66 if (items[currentIndex]) { 67 items[currentIndex].style.opacity = '0'; 68 } 69 70 // After fade out, switch to next item and fade in 71 setTimeout(function () { 72 // Hide current item completely 73 if (items[currentIndex]) { 74 items[currentIndex].classList.remove('ticker__item--active'); 75 items[currentIndex].style.visibility = 'hidden'; 76 } 77 78 // Calculate next index 79 var nextIndex = (currentIndex + 1) % items.length; 80 81 // Show next item 82 if (items[nextIndex]) { 83 items[nextIndex].classList.add('ticker__item--active'); 84 items[nextIndex].style.visibility = 'visible'; 85 items[nextIndex].style.opacity = '0'; 86 87 // Force reflow 88 void items[nextIndex].offsetWidth; 89 90 // Fade in 91 items[nextIndex].style.opacity = '1'; 92 } 93 94 currentIndex = nextIndex; 95 isAnimating = false; 96 97 }, 300); // Match the CSS transition time 98 } 99 100 function advance() { 101 if (!autoRun || pausedByUser || isAnimating) return; 102 103 transitionToNext(); 104 105 if (autoRun && !pausedByUser) { 106 timerId = setTimeout(advance, pauseMs); 107 } 108 } 109 110 function start() { 111 stop(); 112 showItem(0); 113 if (autoRun && items.length > 1) { 114 timerId = setTimeout(advance, pauseMs); 115 } 116 } 117 118 function stop() { 119 if (timerId) { 120 clearTimeout(timerId); 121 timerId = null; 122 } 123 } 124 125 // Pause on hover/focus 126 container.addEventListener('mouseenter', function () { 127 pausedByUser = true; 128 container.classList.add('ticker--paused'); 129 stop(); 130 }); 131 132 container.addEventListener('mouseleave', function () { 133 pausedByUser = false;
134 container.classList.remove('ticker--paused'); 135 if (autoRun && items.length > 1) { 136 timerId = setTimeout(advance, pauseMs); 137 } 138 }); 139 140 container.addEventListener('focusin', function (e) { 141 if (container.contains(e.target)) { 142 pausedByUser = true; 143 container.classList.add('ticker--paused'); 144 stop(); 145 } 146 }); 147 148 container.addEventListener('focusout', function (e) { 149 if (!container.contains(e.relatedTarget)) { 150 pausedByUser = false; 151 container.classList.remove('ticker--paused'); 152 if (autoRun && items.length > 1) { 153 timerId = setTimeout(advance, pauseMs); 154 } 155 } 156 }); 157 158 // Handle image loading and text rendering 159 var imgs = track.querySelectorAll('img'); 160 var pending = imgs.length; 161 162 function checkReady() { 163 if (--pending === 0) { 164 // Small delay to ensure text has rendered 165 setTimeout(function () { 166 start(); 167 }, 100); 168 } 169 } 170 171 if (pending > 0) { 172 imgs.forEach(function (img) { 173 if (img.complete) { 174 checkReady(); 175 } else { 176 img.addEventListener('load', checkReady, { once: true }); 177 img.addEventListener('error', checkReady, { once: true }); 178 } 179 }); 180 } else { 181 // No images, but wait for text rendering 182 setTimeout(function () { 183 start(); 184 }, 100); 185 } 186 187 // Initial setup 188 if (pending === 0) { 189 setTimeout(function () { 190 start(); 191 }, 100); 192 } 193 } 194 195 function bootstrapRoot(root) { 196 (root || document).querySelectorAll('.ticker.ticker--step').forEach(initStepTicker); 197 } 198 199 // Run now, on DOM ready, and after full load 200 if (document.readyState !== 'loading') bootstrapRoot(); 201 document.addEventListener('DOMContentLoaded', function () { bootstrapRoot(); }); 202 window.addEventListener('load', function () { bootstrapRoot(); }); 203 204 // MutationObserver for CMS editing 205 try { 206 var observer = new MutationObserver(function (muts) { 207 var needs = false; 208 for (var i = 0; i < muts.length; i++) { 209 var m = muts[i]; 210 if (m.type === 'childList' && m.addedNodes && m.addedNodes.length) { 211 needs = true; 212 break; 213 } 214 } 215 if (needs) bootstrapRoot(); 216 }); 217 observer.observe(document.documentElement || document.body, { childList: true, subtree: true }); 218 } catch (e) { /* no-op */ } 219})();
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.