1// AOS ANIMATION 2AOS.init({disable: 'mobile'}); 3window.addEventListener('load', AOS.refresh); 4let scrollRef = 0; 5window.addEventListener('scroll', function() { 6 scrollRef <= 10 ? scrollRef++ : AOS.refresh(); 7}); 8 9 10// MOBILE MENU 11$(document).ready(function() { 12 13 // Main flyout/mobile-style navigation 14 let flyoutNavFocusableElements = document.querySelectorAll('.mobile-scroll a, .mobile-scroll input') 15 flyoutNavFocusableElementsState('-1'); // Disable tabbing to hidden links on load (we'll enable on menu button click-to-open below) 16 17 $('.menu-bar').on('click', function() { 18 $(this).toggleClass('in').parents('html').toggleClass('mobile-menu'); 19 $(this).next().toggleClass('in'); 20 21 // Enable/disable flayout menu link tabbing while 22 let menuButton = $(this).get(0); // native dom element 23 if ( menuButton.classList.contains('in') ) flyoutNavFocusableElementsState('0'); 24 else flyoutNavFocusableElementsState('-1'); 25 }); 26 // Pass '0' or '-1' to enable/disable respectively 27 function flyoutNavFocusableElementsState(state) { 28 flyoutNavFocusableElements?.forEach(el => el.setAttribute('tabindex', state)); 29 } 30 31 // $('.mobile-scroll li.menu-item-has-children').on('click', function() { 32 // var aftercl = psuedoClick(this); 33 // var clickafter = psuedoClick(this).after; 34 // if (clickafter == true) { 35 // if (!$(this).hasClass('open')) { 36 // $(this).addClass('open'); 37 // $(this).children('ul').addClass('in'); 38 // } else { 39 // $(this).find('.sub-menu').removeClass('in'); 40 // $(this).removeClass('open'); 41 // $(this).find('li.open').removeClass('open'); 42 // } 43 // } 44 // $('.sub-menu .sub-menu.in li.open').click(function() { 45 // $(this).removeClass('open'); 46 // $(this).children('.sub-menu.in').removeClass('in'); 47 // }) 48 // }); 49 50 $(document).bind('click', function(e) { 51 var $clicked = $(e.target); 52 if (!$clicked.parents().hasClass('main-nav')) { 53 $('.main-nav').find('.in').removeClass('in'); 54 $('html').removeClass('mobile-menu'); 55 56 // $('.login-modal-section').removeClass('active'); 57 } 58 }); 59}); 60function psuedoClick(parentElem) { 61 62 var beforeClicked, 63 afterClicked; 64 65 var parentLeft = parseInt(parentElem.getBoundingClientRect().left, 10), 66 parentTop = parseInt(parentElem.getBoundingClientRect().top, 10); 67 68 var parentWidth = parseInt(window.getComputedStyle(parentElem).width, 10), 69 parentHeight = parseInt(window.getComputedStyle(parentElem).height, 10); 70 71 var before = window.getComputedStyle(parentElem, ':before'); 72 73 var beforeStart = parentLeft + (parseInt(before.getPropertyValue("left"), 10)), 74 beforeEnd = beforeStart + parseInt(before.width, 10); 75 76 var beforeYStart = parentTop + (parseInt(before.getPropertyValue("top"), 10)), 77 beforeYEnd = beforeYStart + parseInt(before.height, 10); 78 79 var after = window.getComputedStyle(parentElem, ':after'); 80 81 var afterStart = parentLeft + (parseInt(after.getPropertyValue("left"), 10)), 82 afterEnd = afterStart + parseInt(after.width, 10); 83 84 var afterYStart = parentTop + (parseInt(after.getPropertyValue("top"), 10)), 85 afterYEnd = afterYStart + parseInt(after.height, 10); 86 87 var mouseX = event.clientX, 88 mouseY = event.clientY; 89 90 beforeClicked = (mouseX >= beforeStart && mouseX <= beforeEnd && mouseY >= beforeYStart && mouseY <= beforeYEnd ? true : false); 91 92 afterClicked = (mouseX >= afterStart && mouseX <= afterEnd && mouseY >= afterYStart && mouseY <= afterYEnd ? true : false); 93 94 return { 95 "before" : beforeClicked, 96 "after" : afterClicked 97 98 }; 99 100} 101 102if ($('.hero-slider-wrapper').length > 0) { 103 $('.hero-slider-wrapper').slick({ 104 slidesToShow: 1, 105 slidesToscroll: 1, 106 arrows: true, 107 infinite: true, 108 speed: 1400, 109 autoplay: true, 110 dots: true, 111 fade: true, 112 autoplaySpeed: 8000, 113 focusOnSelect: true, 114 pauseOnHover: false 115 }) 116 117 $(".hero-slider-wrapper").on( 118 "beforeChange", 119 function (event, slick, currentSlide, nextSlide) { 120 const nextSlideLength = $(slick.$slides[nextSlide]) 121 .find("video").length; 122 if(nextSlideLength>0) { 123 const nextSlideVideo = $(slick.$slides[nextSlide]) 124 .find("video") 125 .get(0); 126 if (nextSlideVideo) { 127 nextSlideVideo.play(); 128 } 129 } else { 130 const currentVideo = $(slick.$slides[currentSlide]) 131 .find("video") 132 .get(0); 133 if (currentVideo) { 134 currentVideo.pause(); 135 } 136 } 137 138 } 139 ); 140} 141 142 143// MODAL SHOW ON PAGE LOAD 144$(window).on('load',function(){ 145 var delayModal = 1500; 146 147 setTimeout(function(){ 148 // More complex exists comparison since jQuery always creates object, even if not found 149 let promotionModal = $('#promotion-modal'); 150 if (!promotionModal || (promotionModal && !promotionModal.modal )) return; 151 $('#promotion-modal').modal('show'); 152 }, delayModal); 153}); 154 155 156// location section for movile 157if ($('.location-btn-mobile').length > 0) { 158 $(document).ready(function() { 159 $(document).on('click', '.location-btn-mobile', function() { 160 $('.location-use-mobile').toggleClass('active'); 161 $(this).toggleClass('active'); 162 }); 163 }); 164} 165 166 167// PRICE CHANGE WASH CARD 168if ($('.price-btn').length > 0) { 169 document.querySelectorAll('.price-btn').forEach(button => { 170 button.addEventListener('click', function() { 171 let newPrice = this.getAttribute('data-price'); 172 const hasDisclaimer = this.getAttribute('data-has-disclaimer'); 173 const targetId = this.getAttribute('data-target'); 174 const buttonLabel = this.getAttribute('data-btn'); 175 const priceType = this.getAttribute('data-type'); 176 const circleText = this.getAttribute('data-circle'); 177 const circleID = 'circle_'+targetId; 178 if (hasDisclaimer === 'true') { 179 newPrice += '<sup>*</sup>'; 180 } 181 changePrice(newPrice, targetId);
182 setActiveButton(this); 183 document.querySelector(`[data-buy="${priceType}"] span`).innerText = buttonLabel; 184 185 let gtmType = priceType.replace(/\d+/g, '') 186 let gtmDuration = this.getAttribute('data-iframe'); 187 gtmDuration = gtmDuration.replace('iframe-', ''); 188 let gtm = `btn_purchase_${gtmType}_${gtmDuration}_${newPrice}`; 189 document.querySelector(`[data-buy="${priceType}"]`)?.setAttribute('data-gtm', gtm); 190 191 if(circleText.trim() != '') { 192 document.getElementById(circleID).style.display = 'flex'; 193 document.getElementById(circleID).querySelector('p').innerText = circleText; 194 } else { 195 document.getElementById(circleID).style.display = 'none'; 196 } 197 }); 198 }); 199 200 function changePrice(newPrice, targetId) { 201 document.getElementById(targetId).innerHTML = `${newPrice}`; 202 } 203 204 function setActiveButton(clickedButton) { 205 const buttons = clickedButton.parentElement.parentElement.querySelectorAll('.price-btn'); 206 buttons.forEach(button => { 207 button.parentElement.classList.remove('active'); 208 }); 209 clickedButton.parentElement.classList.add('active'); 210 } 211} 212 213 214// wash feature collapse 215if ($('.wash-features').length > 0) { 216 $(document).ready(function() { 217 $('.wash-features').on('click', function() { 218 $(this).toggleClass('active'); 219 }); 220 }); 221} 222 223 224// BUY WASH SLIDER FOR MOBILE 225if($(window).width() < 575) { 226 let bawSlick = $('.wash-product-row:not([data-slick-ignore])').slick({ 227 centerMode: true, 228 infinite: false, 229 centerPadding: '60px', 230 slidesToShow: 1, 231 arrows: true 232 }); 233 bawSlick?.slick('slickGoTo', 1) 234} 235 236 237// SERVICES SLIDER FOR MOBILE 238if($(window).width() < 575) { 239 $('.services-row').slick({ 240 centerMode: false, 241 infinite: false, 242 centerPadding: '24px', 243 slidesToShow: 1.3, 244 arrows: false 245 }); 246} 247 248// SERVICES SLIDER FOR MOBILE 249if($(window).width() < 575) { 250 $('.buy-a-wash-services-row').slick({ 251 centerMode: false, 252 infinite: false, 253 centerPadding: '24px', 254 slidesToShow: 1.1, 255 arrows: false, 256 dots: true 257 }); 258} 259 260 261 262// PRICE CHANGE WASH CARD 263if ($('#work-btn-1').length > 0) { 264 if($(window).width() < 575) { 265 266 window.onload = function() { 267 document.querySelector('#work-btn-1 a').classList.add('active'); 268 document.getElementById('how-work1').classList.add('active'); 269 }; 270 271 272 document.addEventListener('DOMContentLoaded', () => { 273 const tabButtons = document.querySelectorAll('.how-work-number-list :where(a, button)'); 274 const tabContents = document.querySelectorAll('.how-work-col'); 275 276 tabButtons.forEach(button => { 277 button.addEventListener('click', () => { 278 const tabId = button.getAttribute('data-target-tab'); 279 280 tabButtons.forEach(btn => btn.classList.remove('active')); 281 tabContents.forEach(content => content.classList.remove('active')); 282 283 button.classList.add('active'); 284 document.getElementById(tabId).classList.add('active'); 285 }); 286 }); 287 }); 288 } 289} 290 291 292// login form 293// location section for movile 294$(document).ready(function() { 295 $('.sign-up-btn').on('click', function() { 296 $('.user-signup').show(); 297 $('.user-login').hide(); 298 }); 299 300 $('.forgot-btn').on('click', function() { 301 $('.user-forgot-password').show(); 302 $('.user-login').hide(); 303 }); 304 305 $('.btn-login-submit').on('click', function() { 306 $('.after-login-wrap').show(); 307 $('.user-login').hide(); 308 }); 309 310 $('.logout-btn').on('click', function() { 311 $('.after-login-wrap').hide(); 312 $('.user-login').show(); 313 }); 314 315 $('.login-modal-close, .accounts-user').on('click', function() { 316 $('.user-forgot-password, .user-signup, .after-login-wrap').hide(); 317 $('.user-login').show(); 318 }); 319}); 320 321 322// Faq Item (Locations list) 323let locationLists = document.querySelectorAll('.location-archive-list'); 324locationLists?.forEach(list => initLocationList(list)); 325function initLocationList(list) { 326 if (!list) return; 327 let listItems = list.querySelectorAll('button'); 328 listItems?.forEach(item => item.addEventListener('click', e => e.target.classList.toggle('open'))); 329} 330 331 332// CAREERS OUR CORE VALUE SLIDER 333if($(window).width() < 1023) { 334 $('.our-value-row').slick({ 335 centerMode: false, 336 infinite: false, 337 centerPadding: '24px', 338 slidesToShow: 2.7,
339 arrows: false, 340 dots: false, 341 responsive: [ 342 { 343 breakpoint: 575, 344 settings: { 345 slidesToShow: 1.2, 346 dots: true 347 } 348 } 349 ] 350 }); 351} 352 353 354 355// wash compare section 356if ($('.copare-btn').length > 0) { 357 $(document).ready(function() { 358 $('.copare-btn').on('click', function() { 359 $('.washing-compare-section').toggleClass('active'); 360 $(this).toggleClass('active'); 361 }); 362 }); 363} 364 365 366 367// ABOUT VOTED SLIDER FOR MOBILE 368if($(window).width() < 575) { 369 $('.voted-row').slick({ 370 centerMode: true, 371 infinite: true, 372 centerPadding: '60px', 373 slidesToShow: 1, 374 arrows: false, 375 autoplay: true, 376 }); 377} 378 379 380 381 382// BUY WASH SLIDER FOR MOBILE 383if($(window).width() < 767) { 384 $('.partners-logo-warp').slick({ 385 infinite: false, 386 slidesToShow: 7.4, 387 arrows: false, 388 dots: true, 389 responsive: [ 390 { 391 breakpoint: 575, 392 settings: { 393 slidesToShow: 3.4, 394 dots: true 395 } 396 } 397 ] 398 }); 399}
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.