1(function($) { 2 'use strict'; 3 4 // 1. Initialize Image Slider 5 var initImageSlider = function($scope) { 6 const carouselContainer = $scope.find('.carousel-container-unique')[0]; 7 if (!carouselContainer) return; 8 9 const wrapper = carouselContainer.querySelector('.carousel-wrapper-unique'); 10 const prevButton = carouselContainer.querySelector('.prev-button-unique'); 11 const nextButton = carouselContainer.querySelector('.next-button-unique'); 12 if (!wrapper || !prevButton || !nextButton) return; 13 14 const updateButtons = () => { 15 if (!wrapper.offsetParent) return; // a little check to avoid errors on hidden elements 16 const scrollEnd = wrapper.scrollWidth - wrapper.clientWidth; 17 prevButton.disabled = wrapper.scrollLeft <= 0; 18 nextButton.disabled = wrapper.scrollLeft >= scrollEnd - 1; 19 }; 20 21 nextButton.addEventListener('click', () => { 22 const firstCard = wrapper.querySelector('.card-unique'); 23 if (!firstCard) return; 24 const cardWidth = firstCard.offsetWidth; 25 const gap = parseInt(window.getComputedStyle(wrapper).gap); 26 wrapper.scrollBy({ left: cardWidth + gap, behavior: 'smooth' }); 27 }); 28 29 prevButton.addEventListener('click', () => { 30 const firstCard = wrapper.querySelector('.card-unique'); 31 if (!firstCard) return; 32 const cardWidth = firstCard.offsetWidth; 33 const gap = parseInt(window.getComputedStyle(wrapper).gap); 34 wrapper.scrollBy({ left: -(cardWidth + gap), behavior: 'smooth' }); 35 }); 36 37 wrapper.addEventListener('scroll', updateButtons, { passive: true }); 38 new ResizeObserver(updateButtons).observe(wrapper); 39 setTimeout(updateButtons, 100); 40 }; 41 42 // 2. Initialize Testimonial Slider 43 var initTestimonialSlider = function($scope) { 44 const slider = $scope.find('.testimonial-section-tslider')[0]; 45 if (!slider) return; 46 47 const wrapper = slider.querySelector('.testimonial-wrapper-tslider'); 48 const prevButton = slider.querySelector('.testimonial-prev-btn-tslider'); 49 const nextButton = slider.querySelector('.testimonial-next-btn-tslider'); 50 if (!wrapper || !prevButton || !nextButton) return; 51 52 const updateButtons = () => { 53 if (!wrapper.offsetParent) return; 54 const scrollEnd = wrapper.scrollWidth - wrapper.clientWidth; 55 prevButton.disabled = wrapper.scrollLeft <= 0; 56 nextButton.disabled = wrapper.scrollLeft >= scrollEnd - 1; 57 }; 58 59 const handleScroll = (direction) => { 60 const firstCard = wrapper.querySelector('.testimonial-card-tslider'); 61 if (!firstCard) return; 62 const gap = parseInt(window.getComputedStyle(wrapper).gap) || 20; 63 const scrollAmount = firstCard.offsetWidth + gap; 64 wrapper.scrollBy({ left: scrollAmount * direction, behavior: 'smooth' }); 65 }; 66 67 nextButton.addEventListener('click', () => handleScroll(1)); 68 prevButton.addEventListener('click', () => handleScroll(-1)); 69 wrapper.addEventListener('scroll', updateButtons, { passive: true }); 70 new ResizeObserver(updateButtons).observe(wrapper); 71 setTimeout(updateButtons, 50); 72 }; 73 74 // 3. Initialize Case Studies Slider 75 var initCaseStudiesSlider = function($scope) { 76 const slider = $scope.find('.latest-work-wslider')[0]; 77 if (!slider) return; 78 79 const wrapper = slider.querySelector('.wslider-wrapper'); 80 const prevButton = slider.querySelector('.wslider-prev-btn'); 81 const nextButton = slider.querySelector('.wslider-next-btn'); 82 if (!wrapper || !prevButton || !nextButton) return; 83 84 const updateButtons = () => { 85 if (!wrapper.offsetParent) return; 86 const scrollEnd = wrapper.scrollWidth - wrapper.clientWidth; 87 prevButton.disabled = wrapper.scrollLeft <= 0; 88 nextButton.disabled = wrapper.scrollLeft >= scrollEnd - 1; 89 }; 90 91 const handleScroll = (direction) => { 92 const firstCard = wrapper.querySelector('.wslider-card'); 93 if (!firstCard) return; 94 const gap = parseInt(window.getComputedStyle(wrapper).gap) || 24; 95 const scrollAmount = firstCard.offsetWidth + gap; 96 wrapper.scrollBy({ left: scrollAmount * direction, behavior: 'smooth' });
97 }; 98 99 nextButton.addEventListener('click', () => handleScroll(1)); 100 prevButton.addEventListener('click', () => handleScroll(-1)); 101 wrapper.addEventListener('scroll', updateButtons, { passive: true }); 102 new ResizeObserver(updateButtons).observe(wrapper); 103 setTimeout(updateButtons, 50); 104 }; 105 106 // 4. Initialize Insights Tabs 107 var initInsightsTabs = function($scope) { 108 const container = $scope.find('.cf-insights-container')[0]; 109 if (!container) return; 110 111 const tabButtons = container.querySelectorAll('.tab-button'); 112 const tabContents = container.querySelectorAll('.tab-content'); 113 114 tabButtons.forEach(button => { 115 button.addEventListener('click', () => { 116 const tabName = button.getAttribute('data-tab'); 117 118 tabButtons.forEach(btn => btn.classList.remove('active')); 119 button.classList.add('active'); 120 121 tabContents.forEach(content => { 122 content.classList.remove('active'); 123 if (content.id === tabName) { 124 content.classList.add('active'); 125 } 126 }); 127 }); 128 }); 129 }; 130 131 // Elementor Frontend Hook 132 $(window).on('elementor/frontend/init', function() { 133 elementorFrontend.hooks.addAction('frontend/element_ready/image-slider-widget.default', initImageSlider); 134 elementorFrontend.hooks.addAction('frontend/element_ready/testimonial-slider-widget.default', initTestimonialSlider); 135 elementorFrontend.hooks.addAction('frontend/element_ready/case-studies-widget.default', initCaseStudiesSlider); 136 elementorFrontend.hooks.addAction('frontend/element_ready/insights-tabs-widget.default', initInsightsTabs); 137 }); 138 139})(jQuery);
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.