1// $(document).ready(function(){ 2// // Define all variables at the top for clarity 3// const $slider = $('.slider'); 4// const progressBar = document.getElementById('progressBar'); 5// const progressContainer = document.getElementById('progressContainer'); 6// const progressClickArea = document.getElementById('progressClickArea'); 7// const totalSlides = $(".slider .slide-items").length; 8// const increment = 100 / totalSlides; 9 10// // Store tab information in a separate object to avoid global scope pollution 11// const tabInfo = { 12// $container: $('.slider-nav'), 13// $tabs: $('.slide-top-btn'), 14// totalWidth: 0, 15// tabWidths: [], 16// originalTabsCount: 9, // Number of original tabs 17// isAnimating: false, 18// scrollTimer: null 19// }; 20 21// $('.slick-prev').addClass('disabled').prop('disabled', true); 22// // Initialize Main Content Slider 23// const $mainSlider = $slider.slick({ 24// slidesToShow: 1, 25// slidesToScroll: 1, 26// speed: 600, 27// dots: false, 28// centerMode: true, 29// focusOnSelect: true, 30// variableWidth: true, 31// prevArrow: $('.slick-prev'), 32// nextArrow: $('.slick-next'), 33// }); 34 35// // Progress bar functionality 36// function initProgressBar() { 37// $slider.on('beforeChange', function(event, slick, currentSlide, nextSlide) { 38// progressBar.style.left = (nextSlide * increment) + '%'; 39// }); 40 41// progressClickArea.addEventListener('click', (event) => { 42// const containerWidth = progressContainer.offsetWidth; 43// const clickPosition = event.offsetX - progressContainer.offsetLeft; 44// const newSlideIndex = Math.floor((clickPosition / containerWidth) * totalSlides); 45// $slider.slick('slickGoTo', newSlideIndex); 46// }); 47// } 48 49// // Tab navigation functionality 50// function initTabNavigation() { 51// // Clone tabs for infinite loop effect 52// setupInfiniteTabLoop(); 53 54// // Calculate tab visibility and setup scroll behavior 55// setupTabScrolling(); 56 57// // Handle tab clicks with special handling for partially visible tabs 58// $(document).off('click', '.slide-top-btn').on('click', '.slide-top-btn', function() { 59// if (tabInfo.isAnimating) return; 60 61// const $this = $(this); 62// const slideIndex = parseInt($this.data('index')); 63 64// // Update active tab (all instances of this tab) 65// $('.slide-top-btn').removeClass('active'); 66// $('.slide-top-btn[data-index="' + slideIndex + '"]').addClass('active'); 67 68// // Check if the clicked tab is not fully visible 69// if (!isTabFullyVisible($this)) { 70// scrollTabIntoView($this); 71// } 72 73// // Go to the corresponding slide 74// $mainSlider.slick('slickGoTo', slideIndex); 75// }); 76 77// // Update active tab when slide changes 78// $mainSlider.on('afterChange', function(event, slick, currentSlide) { 79// // Update active tab (all instances) 80// $('.slide-top-btn').removeClass('active'); 81// $('.slide-top-btn[data-index="' + currentSlide + '"]').addClass('active'); 82 83// // Find the middle set instance of the active tab 84// const $activeTab = findMiddleSetActiveTab(currentSlide); 85 86// // Check if the active tab is not fully visible 87// if (!isTabFullyVisible($activeTab)) { 88// scrollTabIntoView($activeTab); 89// } 90// }); 91// } 92 93// // Helper functions 94// function setupInfiniteTabLoop() { 95// const $tabWrapper = $('.slider-nav'); 96// const $originalTabs = $tabWrapper.children().clone(true); 97 98// // Clone tabs and add to the beginning and end 99// $originalTabs.clone(true).appendTo($tabWrapper); 100// $originalTabs.clone(true).prependTo($tabWrapper); 101// } 102 103// function isTabFullyVisible($tab) { 104// if (!$tab.length) return false;
105 106// const containerLeft = tabInfo.$container.offset().left; 107// const containerRight = containerLeft + tabInfo.$container.width(); 108 109// const tabLeft = $tab.offset().left; 110// const tabRight = tabLeft + $tab.outerWidth(); 111 112// return (tabLeft >= containerLeft && tabRight <= containerRight); 113// } 114 115// function scrollTabIntoView($tab) { 116// if (!$tab.length || tabInfo.isAnimating) return; 117 118// tabInfo.isAnimating = true; 119 120// const containerWidth = tabInfo.$container.width(); 121// const tabOffset = $tab.offset().left; 122// const containerOffset = tabInfo.$container.offset().left; 123// const tabWidth = $tab.outerWidth(); 124// const scrollLeft = tabInfo.$container.scrollLeft(); 125 126// // Calculate how much the tab is outside the container 127// const leftOverflow = containerOffset - tabOffset; 128// const rightOverflow = (tabOffset + tabWidth) - (containerOffset + containerWidth); 129 130// // Calculate the target scroll position 131// let targetScroll = scrollLeft; 132 133// if (leftOverflow > 0) { 134// targetScroll = scrollLeft - leftOverflow - 20; 135// } else if (rightOverflow > 0) { 136// targetScroll = scrollLeft + rightOverflow + 20; 137// } 138 139// // Animate the scroll 140// tabInfo.$container.animate({ 141// scrollLeft: targetScroll 142// }, 300, function() { 143// checkAndLoopTabs(); 144// tabInfo.isAnimating = false; 145// }); 146// } 147 148// function checkAndLoopTabs() { 149// const $container = tabInfo.$container; 150// const scrollLeft = $container.scrollLeft(); 151// let firstSetWidth = 0; 152// let secondSetWidth = 0; 153 154// // Calculate width of first and second set of tabs 155// for (let i = 0; i < tabInfo.originalTabsCount; i++) { 156// firstSetWidth += tabInfo.tabWidths[i]; 157// secondSetWidth += tabInfo.tabWidths[i + tabInfo.originalTabsCount]; 158// } 159 160// // If scrolled past the first set, jump to the middle set 161// if (scrollLeft < firstSetWidth / 2) { 162// $container.scrollLeft(scrollLeft + secondSetWidth); 163// } 164// // If scrolled past the middle set, jump to the first set 165// else if (scrollLeft > firstSetWidth + secondSetWidth * 1.5) { 166// $container.scrollLeft(scrollLeft - secondSetWidth); 167// } 168// } 169 170// function setupTabScrolling() { 171// // Calculate total width of all tabs 172// tabInfo.totalWidth = 0; 173// tabInfo.tabWidths = []; 174 175// $('.slide-top-btn').each(function() { 176// const width = $(this).outerWidth(true); 177// tabInfo.tabWidths.push(width); 178// tabInfo.totalWidth += width; 179// }); 180 181// // Set initial scroll position to show the middle set of tabs 182// let firstSetWidth = 0; 183// for (let i = 0; i < tabInfo.originalTabsCount; i++) { 184// firstSetWidth += tabInfo.tabWidths[i]; 185// } 186// tabInfo.$container.scrollLeft(firstSetWidth); 187 188// // Scroll to make the initially active tab visible 189// const $activeTab = findMiddleSetActiveTab(2); // Curriculum Planning (index 2) 190// if ($activeTab.length) { 191// setTimeout(function() { 192// scrollTabIntoView($activeTab); 193// }, 100); 194// } 195 196// // Monitor scroll events for looping 197// tabInfo.$container.off('scroll').on('scroll', function() { 198// if (tabInfo.isAnimating) return; 199 200// clearTimeout(tabInfo.scrollTimer); 201// tabInfo.scrollTimer = setTimeout(function() { 202// checkAndLoopTabs(); 203// }, 100); 204// }); 205// } 206 207// function findMiddleSetActiveTab(index) { 208// const $allInstances = $('.slide-top-btn[data-index="' + index + '"]'); 209 210// if ($allInstances.length > 1) { 211// return $allInstances.eq(Math.floor($allInstances.length / 2)); 212// } 213 214// return $allInstances.first(); 215// } 216
217// // Window resize handler 218// $(window).off('resize.tabNav').on('resize.tabNav', function() { 219// setupTabScrolling(); 220 221// const activeIndex = $('.slider').slick('slickCurrentSlide'); 222// const $activeTab = findMiddleSetActiveTab(activeIndex); 223// if ($activeTab.length && !isTabFullyVisible($activeTab)) { 224// scrollTabIntoView($activeTab); 225// } 226// }); 227 228// // Initialize everything 229// initProgressBar(); 230// initTabNavigation(); 231// }); 232$(document).ready(function(){ 233 // Initialize main slider 234 const $slider = $('.slider'); 235 const progressBar = document.getElementById('progressBar'); 236 const progressContainer = document.getElementById('progressContainer'); 237 const progressClickArea = document.getElementById('progressClickArea'); 238 const totalSlides = $(".slider .slide-items").length; 239 const increment = 100 / totalSlides; 240 241 $('.slick-prev').addClass('disabled').prop('disabled', true); 242 243 // Initialize main content slider 244 $slider.slick({ 245 slidesToShow: 1, 246 slidesToScroll: 1, 247 speed: 600, 248 dots: false, 249 centerMode: true, 250 focusOnSelect: true, 251 variableWidth: true, 252 prevArrow: $('.slick-prev'), 253 nextArrow: $('.slick-next'), 254 }); 255 256 // Progress bar functionality 257 $slider.on('beforeChange', function(event, slick, currentSlide, nextSlide) { 258 progressBar.style.left = (nextSlide * increment) + '%'; 259 260 // Enable the slick-prev button if we're not on the first slide 261 if (nextSlide > 0) { 262 $('.slick-prev').removeClass('disabled').prop('disabled', false); 263 } else { 264 // Disable the slick-prev button if we're on the first slide 265 $('.slick-prev').addClass('disabled').prop('disabled', true); 266 } 267 268 // Optionally handle slick-next button state 269 if (nextSlide === totalSlides - 1) { 270 $('.slick-next').addClass('disabled').prop('disabled', true); 271 } else { 272 $('.slick-next').removeClass('disabled').prop('disabled', false); 273 } 274 275 // Update active tab 276 $('.slide-top-btn').removeClass('active'); 277 $(`.slide-top-btn[data-index="${nextSlide}"]`).addClass('active'); 278 279 // Scroll tab into view if needed 280 scrollTabIntoView(nextSlide); 281 }); 282 283 // Handle progress bar clicks 284 progressClickArea.addEventListener('click', (event) => { 285 const containerWidth = progressContainer.offsetWidth; 286 const clickPosition = event.offsetX; 287 const newSlideIndex = Math.floor((clickPosition / containerWidth) * totalSlides); 288 $slider.slick('slickGoTo', newSlideIndex); 289 }); 290 291 // Handle tab clicks 292 $('.slide-top-btn').on('click', function() { 293 const slideIndex = parseInt($(this).data('index')); 294 $slider.slick('slickGoTo', slideIndex); 295 }); 296 297 // Function to scroll tab into view 298 function scrollTabIntoView(index) { 299 const $tab = $(`.slide-top-btn[data-index="${index}"]`); 300 if (!$tab.length) return; 301 302 const $container = $('.slider-nav'); 303 const containerLeft = $container.offset().left; 304 const containerRight = containerLeft + $container.width(); 305 const tabLeft = $tab.offset().left; 306 const tabRight = tabLeft + $tab.outerWidth(); 307 308 // Check if tab is fully visible 309 if (tabLeft < containerLeft || tabRight > containerRight) { 310 // Calculate scroll position to center the tab 311 const scrollAmount = tabLeft - containerLeft - ($container.width() / 2) + ($tab.outerWidth() / 2); 312 313 // Smooth scroll to position 314 $container.animate({ 315 scrollLeft: $container.scrollLeft() + scrollAmount 316 }, 300); 317 } 318 } 319 320 // Set initial active tab and position 321 setTimeout(function() { 322 // Get initial slide index 323 const initialSlide = $slider.slick('slickCurrentSlide'); 324 325 // Update active tab 326 $('.slide-top-btn').removeClass('active'); 327 $(`.slide-top-btn[data-index="${initialSlide}"]`).addClass('active'); 328 329 // Scroll to active tab 330 scrollTabIntoView(initialSlide); 331 }, 100); 332 333 // Handle window resize 334 $(window).on('resize', function() { 335 const currentSlide = $slider.slick('slickCurrentSlide'); 336 scrollTabIntoView(currentSlide); 337 }); 338});
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.