1/** 2 * 3 */ 4( function() { 5 6 var carousels; 7 8 document.addEventListener( "DOMContentLoaded", initCarousel ); 9 10 function initCarousel() { 11 12 carousels = document.querySelectorAll( ".flairousel" ); 13 14 carousels.forEach( function( el ) { 15 observe( el ); 16 var w = wrapCarousel( el ); 17 // w.dataset.slideDist = getSlideDistance( w ); 18 addPrevNextButtons( w ); 19 addDots( w ); 20 updateButtons( w ); 21 22 }); 23 24 } 25 26 function getSlideDistance( el ) { 27 var cols = el.querySelectorAll( ".flairousel > div" ); 28 var cols = [...cols]; 29 30 var rect = cols[0].getBoundingClientRect(); 31 var rect2 = cols[1].getBoundingClientRect(); 32 33 return (rect2.width - ( rect.width + rect.left )) * -1; 34 35 } 36 37 function observe( el ) { 38 var rect = el.getBoundingClientRect(); 39 40 if ('IntersectionObserver' in window) { 41 var options = { 42 root: el, 43 rootMargin: '0px', 44 threshold: [0, 0.2, 0.6, 0.8, 1] 45// threshold: buildThreshold( ( rect.width / 60 ) ) 46 } 47 var observer = new IntersectionObserver(observerCallback, options); 48 var els = el.querySelectorAll(":scope > div"); 49 50 els.forEach(function( el ) { 51 observer.observe(el); 52 }); 53 } 54 } 55 56 function observerCallback(entries, observer) { 57 entries.every(function(entry) { 58 entry.target.dataset.intersection = entry.intersectionRatio; 59 entry.target.dataset.isIntersecting = entry.isIntersecting; 60 if( entry.intersectionRatio > .6 ) { 61 var c = entry.target.parentNode; 62 var wrap = c.parentNode; 63 var index = Array.prototype.indexOf.call( c.children, entry.target ); 64 65 // this is where the dots are getting messed up on doubles and triples... 66 // we need this to "auto-detect" the slide position when the user scrolls 67 // but it misbehaves when a the user clicks a dot/button 68 // the "fix" is the callbackCallBack function that limits execution 69 // to just the last iteration. 70 // it mostly works 71 // wrap.dataset.slideIndex = index; 72 // updateButtons( wrap ); 73 return false; 74 } 75 return true; 76 }); 77 callbackCallBack(entries[0].target.parentNode); 78 } 79 80 function callbackCallBack( carousel ) { 81 var els = carousel.querySelectorAll(":scope > div"); 82 els = [...els]; 83 els.every(function( el ) { 84 if( el.dataset.intersection > .6 && el.dataset.isIntersecting ) { 85 86 var wrap = carousel.parentNode; 87 var index = Array.prototype.indexOf.call( carousel.children, el ); 88 wrap.dataset.slideIndex = index; 89 90 updateButtons( wrap ); 91 return false; 92 } 93 return true; 94 }); 95 } 96 97 function buildThreshold(num) { 98 let thresholds = []; 99 100 for (let i=1.0; i<=num; i++) { 101 let ratio = i/num; 102 thresholds.push(ratio); 103 } 104 105 thresholds.push(0); 106 return thresholds; 107 } 108 109 110 function updatePosition( el ) { 111 var xer = (el.dataset.xer * 1); 112 // sanity check 113 var index = el.dataset.slideIndex; 114 if ( index < 0 ) { 115 index = 0; 116 el.dataset.slideIndex = index; 117 } 118 var max = ( el.dataset.slideCount * 1 ) + 1 - xer; 119 el.dataset.max = max; 120 if ( index > max ) { 121 index = max; 122 el.dataset.slideIndex = index; 123 } 124 // end sanity check 125 126 var c = el.querySelector( ".flairousel" ); 127 var rect = el.getBoundingClientRect(); 128 var dist = rect.width / (el.dataset.xer * 1); 129 c.scrollLeft = dist * index; 130 131 132// c.scrollLeft = Math.floor( el.dataset.slideDist * index ); 133 134 // updateButtons( el ); // IntersectionObserver handles this 135 } 136 137 function updateButtons( el ) { 138 var xer = el.dataset.xer * 1; 139 var dots = el.querySelectorAll( ".dot" ); 140 dots.forEach( function( d ) { 141 if( d.dataset.slideIndex == el.dataset.slideIndex ) { 142 d.dataset.isSelected = 1; 143 } else { 144 d.dataset.isSelected = 0; 145 } 146 }); 147 148 var p = el.querySelector(".previous"); 149 var n = el.querySelector(".next"); 150 p.classList.remove('disabled'); 151 n.classList.remove('disabled'); 152 if( 0 == el.dataset.slideIndex ) { 153 p.classList.add('disabled'); 154 } 155 if( el.dataset.slideCount-xer == el.dataset.slideIndex ) { 156 n.classList.add('disabled'); 157 } 158 159 } 160 161 162 function wrapCarousel( el ) { 163 var wrap = document.createElement("DIV"); 164 wrap.classList.add("flairousel-wrap"); 165 el.parentNode.insertBefore( wrap, el ); 166 wrap.appendChild( el ); 167 168 var slides = el.querySelectorAll(":scope > div"); 169 wrap.dataset.slideCount = slides.length; 170 wrap.dataset.slideIndex = 0; 171 172 wrap.dataset.xer = 1; 173 var rect = wrap.getBoundingClientRect(); 174 175 if( rect.width > 400 && el.classList.contains( "double" ) ) { 176 wrap.dataset.xer = 2; 177 } 178 179 // this is a pretty kludgy way to manage responsive columns 180 // maybe css vars would be better, ala el.setProperty( '--foo', bar ); 181 if( el.classList.contains( "triple" ) ) { 182 if ( rect.width > 640 ) { 183 wrap.dataset.xer = 3; 184 } else { 185 el.classList.remove( "triple" ); 186 el.classList.add( "double" ); 187 wrap.dataset.xer = 2; 188 } 189 } 190 191 return wrap; 192 } 193 194 195 function addDots( el ) { 196 var dot, c, dots, slides, i; 197 198 c = el.querySelector( ".carousel" ); 199 200 dots = document.createElement("DIV"); 201 dots.classList.add("dots"); 202 el.appendChild(dots); 203 el.classList.add("has-dots"); 204 205 for( i=0; i<el.dataset.slideCount; i++ ) { 206 (function(i){ 207 dot = document.createElement("BUTTON"); 208 dot.classList.add("dot"); 209 dot.dataset.slideIndex = i; 210 dot.addEventListener( "click", function() { 211 el.dataset.slideIndex = i; 212 updatePosition( el ); 213 }); 214 dots.appendChild(dot); 215 })(i) 216 } 217 218 } 219 220 221 function addPrevNextButtons( el ) { 222 var f, r; 223 var c = el.querySelector( ".flairousel" ); 224 var xer = (el.dataset.xer * 1); 225 r = document.createElement("BUTTON"); 226 r.innerHTML = "Previous"; 227 r.classList.add("previous"); 228 r.addEventListener( "click", function() { 229 el.dataset.slideIndex = (el.dataset.slideIndex*1) - xer; 230 updatePosition( el ); 231 }); 232 el.appendChild(r); 233 234 f = document.createElement("BUTTON"); 235 f.innerHTML = "Next"; 236 f.classList.add("next"); 237 f.addEventListener( "click", function() { 238 el.dataset.slideIndex = (el.dataset.slideIndex*1) + xer; 239 updatePosition( el ); 240 }); 241 el.appendChild(f); 242 243 el.classList.add("has-buttons"); 244 245 } 246 247 248 249})();
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.