1(function ($) { 2 ("use strict"); 3 /*================================= 4 JS Index Here 5 ==================================*/ 6 /* 7 01. On Load Function 8 02. Preloader 9 03. Mobile Menu Active 10 04. Sticky fix 11 05. Scroll To Top 12 06. Set Background Image 13 07. Popup Sidemenu 14 08. Global Slider 15 09. Ajax Contact Form 16 10. Magnific Popup 17 11. Filter 18 12. Counter section 19 13. Progress Bar 20 14. Search Box Popup 21 15. Woocommerce Toggle 22 16. Nice Select 23 17. process style 24 18. WOW js Animation 25 19. particlesJS Animation 26 20. map active 27 21. team active 28 */ 29 /*================================= 30 JS Index End 31 ==================================*/ 32 /* 33 34 /*---------- 01. On Load Function ----------*/ 35 $(window).on("load", function () { 36 $(".preloader").fadeOut(); 37 }); 38 39 /*---------- 02. Preloader ----------*/ 40 if ($(".preloader").length > 0) { 41 $(".preloaderCls").each(function () { 42 $(this).on("click", function (e) { 43 e.preventDefault(); 44 $(".preloader").css("display", "none"); 45 }); 46 }); 47 } 48 49 /*---------- 03. Mobile Menu Active ----------*/ 50 $.fn.vsmobilemenu = function (options) { 51 var opt = $.extend( 52 { 53 menuToggleBtn: ".vs-menu-toggle", 54 bodyToggleClass: "vs-body-visible", 55 subMenuClass: "vs-submenu", 56 subMenuParent: "vs-item-has-children", 57 subMenuParentToggle: "vs-active", 58 meanExpandClass: "vs-mean-expand", 59 appendElement: '<span class="vs-mean-expand"></span>', 60 subMenuToggleClass: "vs-open", 61 toggleSpeed: 400, 62 }, 63 options 64 ); 65 66 return this.each(function () { 67 var menu = $(this); // Select menu 68 69 // Menu Show & Hide 70 function menuToggle() { 71 menu.toggleClass(opt.bodyToggleClass); 72 73 // collapse submenu on menu hide or show 74 var subMenu = "." + opt.subMenuClass; 75 $(subMenu).each(function () { 76 if ($(this).hasClass(opt.subMenuToggleClass)) { 77 $(this).removeClass(opt.subMenuToggleClass); 78 $(this).css("display", "none"); 79 $(this).parent().removeClass(opt.subMenuParentToggle); 80 } 81 }); 82 } 83 84 // Class Set Up for every submenu 85 menu.find("li").each(function () { 86 var submenu = $(this).find("ul"); 87 submenu.addClass(opt.subMenuClass); 88 submenu.css("display", "none"); 89 submenu.parent().addClass(opt.subMenuParent); 90 submenu.prev("a").append(opt.appendElement); 91 submenu.next("a").append(opt.appendElement); 92 }); 93 94 // Toggle Submenu 95 function toggleDropDown($element) { 96 if ($($element).next("ul").length > 0) { 97 $($element).parent().toggleClass(opt.subMenuParentToggle); 98 $($element).next("ul").slideToggle(opt.toggleSpeed); 99 $($element).next("ul").toggleClass(opt.subMenuToggleClass); 100 } else if ($($element).prev("ul").length > 0) { 101 $($element).parent().toggleClass(opt.subMenuParentToggle); 102 $($element).prev("ul").slideToggle(opt.toggleSpeed); 103 $($element).prev("ul").toggleClass(opt.subMenuToggleClass); 104 } 105 } 106 107 // Submenu toggle Button 108 var expandToggler = "." + opt.meanExpandClass; 109 $(expandToggler).each(function () { 110 $(this).on("click", function (e) { 111 e.preventDefault(); 112 toggleDropDown($(this).parent()); 113 }); 114 }); 115 116 // Menu Show & Hide On Toggle Btn click 117 $(opt.menuToggleBtn).each(function () { 118 $(this).on("click", function () { 119 menuToggle(); 120 }); 121 }); 122 123 // Hide Menu On out side click 124 menu.on("click", function (e) { 125 e.stopPropagation(); 126 menuToggle(); 127 }); 128 129 // Stop Hide full menu on menu click 130 menu.find("div").on("click", function (e) { 131 e.stopPropagation(); 132 }); 133 }); 134 }; 135 136 $(".vs-menu-wrapper").vsmobilemenu(); 137 138 /*---------- 04. Sticky fix ----------*/ 139 var lastScrollTop = ""; 140 var scrollToTopBtn = ".scrollToTop"; 141 142 function stickyMenu($targetMenu, $toggleClass, $parentClass) { 143 var st = $(window).scrollTop(); 144 var height = $targetMenu.css("height"); 145 $targetMenu.parent().css("min-height", height); 146 if ($(window).scrollTop() > 800) { 147 $targetMenu.parent().addClass($parentClass); 148 149 if (st > lastScrollTop) { 150 $targetMenu.removeClass($toggleClass); 151 } else { 152 $targetMenu.addClass($toggleClass); 153 } 154 } else { 155 $targetMenu.parent().css("min-height", "").removeClass($parentClass); 156 $targetMenu.removeClass($toggleClass); 157 } 158 lastScrollTop = st; 159 } 160 $(window).on("scroll", function () { 161 stickyMenu($(".sticky-active"), "active", "will-sticky"); 162 if ($(this).scrollTop() > 500) { 163 $(scrollToTopBtn).addClass("show"); 164 } else { 165 $(scrollToTopBtn).removeClass("show"); 166 } 167 }); 168 169 /*---------- 05. Scroll To Top ----------*/ 170 $(scrollToTopBtn).each(function () { 171 $(this).on("click", function (e) { 172 e.preventDefault(); 173 $("html, body").animate( 174 { 175 scrollTop: 0, 176 }, 177 lastScrollTop / 3 178 ); 179 return false; 180 });
181 }); 182 183 /*---------- 06. Set Background Image ----------*/ 184 if ($("[data-bg-src]").length > 0) { 185 $("[data-bg-src]").each(function () { 186 var src = $(this).attr("data-bg-src"); 187 $(this).css("background-image", "url(" + src + ")"); 188 $(this).removeAttr("data-bg-src").addClass("background-image"); 189 }); 190 } 191 /*---------- 07. Popup Sidemenu ----------*/ 192 function popupSideMenu($sideMenu, $sideMunuOpen, $sideMenuCls, $toggleCls) { 193 // Sidebar Popup 194 $($sideMunuOpen).on("click", function (e) { 195 e.preventDefault(); 196 $($sideMenu).addClass($toggleCls); 197 }); 198 $($sideMenu).on("click", function (e) { 199 e.stopPropagation(); 200 $($sideMenu).removeClass($toggleCls); 201 }); 202 var sideMenuChild = $sideMenu + " > div"; 203 $(sideMenuChild).on("click", function (e) { 204 e.stopPropagation(); 205 $($sideMenu).addClass($toggleCls); 206 }); 207 $($sideMenuCls).on("click", function (e) { 208 e.preventDefault(); 209 e.stopPropagation(); 210 $($sideMenu).removeClass($toggleCls); 211 }); 212 } 213 popupSideMenu( 214 ".sidemenu-wrapper", 215 ".sideMenuToggler", 216 ".sideMenuCls", 217 "show" 218 ); 219 220 /*----------- 08. Global Slider ----------*/ 221 $(".vs-carousel").each(function () { 222 var asSlide = $(this); 223 224 // Collect Data 225 function d(data) { 226 return asSlide.data(data); 227 } 228 229 // Custom Arrow Button 230 var prevButton = 231 '<button type="button" class="slick-prev"><i class="' + 232 d("prev-arrow") + 233 '"></i></button>', 234 nextButton = 235 '<button type="button" class="slick-next"><i class="' + 236 d("next-arrow") + 237 '"></i></button>'; 238 239 // Function For Custom Arrow Btn 240 $("[data-slick-next]").each(function () { 241 $(this).on("click", function (e) { 242 e.preventDefault(); 243 $($(this).data("slick-next")).slick("slickNext"); 244 }); 245 }); 246 247 $("[data-slick-prev]").each(function () { 248 $(this).on("click", function (e) { 249 e.preventDefault(); 250 $($(this).data("slick-prev")).slick("slickPrev"); 251 }); 252 }); 253 254 // Check for arrow wrapper 255 if (d("arrows") == true) { 256 if (!asSlide.closest(".arrow-wrap").length) { 257 asSlide.closest(".container").parent().addClass("arrow-wrap"); 258 } 259 } 260 261 asSlide.slick({ 262 dots: d("dots") ? true : false, 263 fade: d("fade") ? true : false, 264 arrows: d("arrows") ? true : false, 265 speed: d("speed") ? d("speed") : 1000, 266 asNavFor: d("asnavfor") ? d("asnavfor") : false, 267 autoplay: d("autoplay") == true ? true : false, 268 infinite: d("infinite") == false ? false : true, 269 slidesToShow: d("slide-show") ? d("slide-show") : 1, 270 adaptiveHeight: d("adaptive-height") ? true : false, 271 centerMode: d("center-mode") ? true : false, 272 autoplaySpeed: d("autoplay-speed") ? d("autoplay-speed") : 8000, 273 centerPadding: d("center-padding") ? d("center-padding") : "0", 274 focusOnSelect: d("focuson-select") == false ? false : true, 275 pauseOnFocus: d("pauseon-focus") ? true : false, 276 pauseOnHover: d("pauseon-hover") ? true : false, 277 variableWidth: d("variable-width") ? true : false, 278 vertical: d("vertical") ? true : false, 279 verticalSwiping: d("vertical") ? true : false, 280 prevArrow: d("prev-arrow") 281 ? prevButton 282 : '<button type="button" class="slick-prev"><i class="fa-regular fa-arrow-left"></i></button>', 283 nextArrow: d("next-arrow") 284 ? nextButton 285 : '<button type="button" class="slick-next"><i class="fa-regular fa-arrow-right"></i></button>', 286 rtl: $("html").attr("dir") == "rtl" ? true : false, 287 responsive: [ 288 { 289 breakpoint: 1600, 290 settings: { 291 arrows: d("xl-arrows") ? true : false, 292 dots: d("xl-dots") ? true : false, 293 slidesToShow: d("xl-slide-show") 294 ? d("xl-slide-show") 295 : d("slide-show"), 296 centerMode: d("xl-center-mode") ? true : false, 297 centerPadding: 0, 298 }, 299 }, 300 { 301 breakpoint: 1400, 302 settings: { 303 arrows: d("ml-arrows") ? true : false, 304 dots: d("ml-dots") ? true : false, 305 slidesToShow: d("ml-slide-show") 306 ? d("ml-slide-show") 307 : d("slide-show"), 308 centerMode: d("ml-center-mode") ? true : false, 309 centerPadding: 0, 310 }, 311 }, 312 { 313 breakpoint: 1200, 314 settings: { 315 arrows: d("lg-arrows") ? true : false, 316 dots: d("lg-dots") ? true : false, 317 // vertical:d("lg-vertical") ? true : false, 318 slidesToShow: d("lg-slide-show") 319 ? d("lg-slide-show") 320 : d("slide-show"), 321 centerMode: d("lg-center-mode") ? d("lg-center-mode") : false, 322 centerPadding: 0, 323 }, 324 }, 325 { 326 breakpoint: 992, 327 settings: { 328 arrows: d("md-arrows") ? true : false, 329 dots: d("md-dots") ? true : false, 330 vertical: d("md-vertical") ? true : false, 331 slidesToShow: d("md-slide-show") ? d("md-slide-show") : 1, 332 centerMode: d("md-center-mode") ? d("md-center-mode") : false, 333 centerPadding: 0, 334 }, 335 }, 336 { 337 breakpoint: 767, 338 settings: { 339 arrows: d("sm-arrows") ? true : false, 340 dots: d("sm-dots") ? true : false, 341 vertical: d("sm-vertical") ? true : false, 342 slidesToShow: d("sm-slide-show") ? d("sm-slide-show") : 1, 343 centerMode: d("sm-center-mode") ? d("sm-center-mode") : false, 344 centerPadding: 0, 345 }, 346 }, 347 { 348 breakpoint: 576, 349 settings: { 350 arrows: d("xs-arrows") ? true : false, 351 dots: d("xs-dots") ? true : false, 352 vertical: d("xs-vertical") ? true : false, 353 slidesToShow: d("xs-slide-show") ? d("xs-slide-show") : 1, 354 centerMode: d("xs-center-mode") ? d("xs-center-mode") : false, 355 centerPadding: 0, 356 }, 357 }, 358 // You can unslick at a given breakpoint now by adding: 359 // settings: "unslick" 360 // instead of a settings object 361 ], 362 });
363 }); 364 365 /*----------- 09. Ajax Contact Form ----------*/ 366 var form = ".ajax-contact"; 367 var invalidCls = "is-invalid"; 368 var $email = '[name="email"]'; 369 var $validation = 370 '[name="name"],[name="email"],[name="subject"],[name="message"]'; // Must be use (,) without any space 371 var formMessages = $(".form-messages"); 372 373 function sendContact() { 374 var formData = $(form).serialize(); 375 var valid; 376 valid = validateContact(); 377 if (valid) { 378 jQuery 379 .ajax({ 380 url: $(form).attr("action"), 381 data: formData, 382 type: "POST", 383 }) 384 .done(function (response) { 385 // Make sure that the formMessages div has the 'success' class. 386 formMessages.removeClass("error"); 387 formMessages.addClass("success"); 388 // Set the message text. 389 formMessages.text(response); 390 // Clear the form. 391 $(form + ' input:not([type="submit"]),' + form + " textarea").val(""); 392 }) 393 .fail(function (data) { 394 // Make sure that the formMessages div has the 'error' class. 395 formMessages.removeClass("success"); 396 formMessages.addClass("error"); 397 // Set the message text. 398 if (data.responseText !== "") { 399 formMessages.html(data.responseText); 400 } else { 401 formMessages.html( 402 "Oops! An error occured and your message could not be sent." 403 ); 404 } 405 }); 406 } 407 } 408 409 function validateContact() { 410 var valid = true; 411 var formInput; 412 413 function unvalid($validation) { 414 $validation = $validation.split(","); 415 for (var i = 0; i < $validation.length; i++) { 416 formInput = form + " " + $validation[i]; 417 if (!$(formInput).val()) { 418 $(formInput).addClass(invalidCls); 419 valid = false; 420 } else { 421 $(formInput).removeClass(invalidCls); 422 valid = true; 423 } 424 } 425 } 426 unvalid($validation); 427 428 if ( 429 !$($email).val() || 430 !$($email) 431 .val() 432 .match(/^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/) 433 ) { 434 $($email).addClass(invalidCls); 435 valid = false; 436 } else { 437 $($email).removeClass(invalidCls); 438 valid = true; 439 } 440 return valid; 441 } 442 443 $(form).on("submit", function (element) { 444 element.preventDefault(); 445 sendContact(); 446 }); 447 448 /*----------- 10. Magnific Popup ----------*/ 449 /* magnificPopup img view */ 450 $(".popup-image").magnificPopup({ 451 type: "image", 452 gallery: { 453 enabled: true, 454 }, 455 }); 456 457 /* magnificPopup video view */ 458 $(".popup-video").magnificPopup({ 459 type: "iframe", 460 }); 461 462 /*----------- 11. Filter ----------*/ 463 $(".filter-active").imagesLoaded(function () { 464 var $filter = ".filter-active", 465 $filterItem = ".filter-item", 466 $filterMenu = ".filter-menu-active"; 467 468 if ($($filter).length > 0) { 469 var $grid = $($filter).isotope({ 470 itemSelector: $filterItem, 471 filter: "*", 472 masonry: { 473 // use outer width of grid-sizer for columnWidth 474 columnWidth: 1, 475 }, 476 }); 477 478 // filter items on button click 479 $($filterMenu).on("click", "button", function () { 480 var filterValue = $(this).attr("data-filter"); 481 $grid.isotope({ 482 filter: filterValue, 483 }); 484 }); 485 486 // Menu Active Class 487 $($filterMenu).on("click", "button", function (event) { 488 event.preventDefault(); 489 $(this).addClass("active"); 490 $(this).siblings(".active").removeClass("active"); 491 }); 492 } 493 }); 494 495 496 497 /*----------- 12. Counter section ----------*/ 498 var a = 0; 499 500 $(window).scroll(function () { 501 var mediaCounter = $(".media-counter"); 502 503 if (mediaCounter.length > 0) { 504 var oTop = mediaCounter.offset().top - window.innerHeight; 505 506 if (a == 0 && $(window).scrollTop() > oTop) { 507 $(".counter-number").each(function () { 508 var $this = $(this), 509 countTo = $this.attr("data-count"); 510 $({ countNum: $this.text() }).animate( 511 { 512 countNum: countTo, 513 }, 514 { 515 duration: 4000, 516 easing: "swing", 517 step: function () { 518 $this.text(Math.floor(this.countNum)); 519 }, 520 complete: function () { 521 $this.text(this.countNum); 522 //alert('finished'); 523 }, 524 } 525 ); 526 }); 527 a = 1; 528 } 529 } 530 }); 531 532 /*----------- 13. Progress Bar ----------*/ 533 document.addEventListener("DOMContentLoaded", function () { 534 const progressBoxes = document.querySelectorAll(".progress-box"); 535 536 const options = { 537 root: null, 538 rootMargin: "0px", 539 threshold: 0.5, // Intersection observer threshold 540 }; 541 542 const observer = new IntersectionObserver((entries, observer) => {
543 entries.forEach((entry) => { 544 if (entry.isIntersecting) { 545 animateProgressBar(entry.target); 546 observer.unobserve(entry.target); 547 } 548 }); 549 }, options); 550 551 progressBoxes.forEach((progressBox) => { 552 observer.observe(progressBox); 553 }); 554 555 function animateProgressBar(progressBox) { 556 const progressBar = progressBox.querySelector(".progress-box__bar"); 557 const progressNumber = progressBox.querySelector(".progress-box__number"); 558 const targetWidth = parseInt(progressBar.style.width, 10); // Explicit radix 10 559 let width = 0; 560 561 const countInterval = setInterval(() => { 562 width++; 563 progressBar.style.width = width + "%"; 564 progressNumber.textContent = width + "%"; 565 if (width >= targetWidth) { 566 clearInterval(countInterval); 567 } 568 }, 20); 569 } 570}); 571 572 573 574/*---------- 14. Search Box Popup ----------*/ 575 function popupSarchBox($searchBox, $searchOpen, $searchCls, $toggleCls) { 576 $($searchOpen).on("click", function (e) { 577 e.preventDefault(); 578 $($searchBox).addClass($toggleCls); 579 }); 580 $($searchBox).on("click", function (e) { 581 e.stopPropagation(); 582 $($searchBox).removeClass($toggleCls); 583 }); 584 $($searchBox) 585 .find("form") 586 .on("click", function (e) { 587 e.stopPropagation(); 588 $($searchBox).addClass($toggleCls); 589 }); 590 $($searchCls).on("click", function (e) { 591 e.preventDefault(); 592 e.stopPropagation(); 593 $($searchBox).removeClass($toggleCls); 594 }); 595 } 596 popupSarchBox( 597 ".popup-search-box", 598 ".searchBoxTggler", 599 ".searchClose", 600 "show" 601 ); 602 603 /*----------- 15. Woocommerce Toggle ----------*/ 604 // Ship To Different Address 605 $("#ship-to-different-address-checkbox").on("change", function () { 606 if ($(this).is(":checked")) { 607 $("#ship-to-different-address").next(".shipping_address").slideDown(); 608 } else { 609 $("#ship-to-different-address").next(".shipping_address").slideUp(); 610 } 611 }); 612 613 // Login Toggle 614 $(".woocommerce-form-login-toggle a").on("click", function (e) { 615 e.preventDefault(); 616 $(".woocommerce-form-login").slideToggle(); 617 }); 618 619 // Coupon Toggle 620 $(".woocommerce-form-coupon-toggle a").on("click", function (e) { 621 e.preventDefault(); 622 $(".woocommerce-form-coupon").slideToggle(); 623 }); 624 625 // Woocommerce Shipping Method 626 $(".shipping-calculator-button").on("click", function (e) { 627 e.preventDefault(); 628 $(this).next(".shipping-calculator-form").slideToggle(); 629 }); 630 631 // Woocommerce Payment Toggle 632 $('.wc_payment_methods input[type="radio"]:checked') 633 .siblings(".payment_box") 634 .show(); 635 $('.wc_payment_methods input[type="radio"]').each(function () { 636 $(this).on("change", function () { 637 $(".payment_box").slideUp(); 638 $(this).siblings(".payment_box").slideDown(); 639 }); 640 }); 641 642 // Woocommerce Rating Toggle 643 $(".rating-select .stars a").each(function () { 644 $(this).on("click", function (e) { 645 e.preventDefault(); 646 $(this).siblings().removeClass("active"); 647 $(this).parent().parent().addClass("selected"); 648 $(this).addClass("active"); 649 }); 650 }); 651 652/*----------- 16. Nice Select ----------*/ 653 if ($("select").length > 0) { 654 $("select").niceSelect(); 655 } 656 657 $(".project-item,.team-style,.price-style2").hover(function () { 658 $(".project-item,.team-style,.price-style2").removeClass("active"); 659 $(this).addClass("active"); 660 }); 661 662/*----------- 17. process-style ----------*/ 663// Function to toggle active class and height 664function toggleActiveItem(clickedItem) { 665 const processItems = document.querySelectorAll(".process-style1"); 666 667 processItems.forEach((item) => { 668 const content = item.querySelector(".accordion-collapse"); 669 if (item === clickedItem) { 670 item.classList.add("active"); 671 if (content) content.style.height = content.scrollHeight + "px"; 672 } else { 673 item.classList.remove("active"); 674 if (content) content.style.height = "0"; 675 } 676 677 // Enable or disable the button 678 const button = item.querySelector(".accordion-button"); 679 if (button) button.disabled = item.classList.contains("active"); 680 }); 681} 682 683// Initial setup for buttons and content height 684function initialize() { 685 const processItems = document.querySelectorAll(".process-style1"); 686
687 processItems.forEach((item) => { 688 const content = item.querySelector(".accordion-collapse"); 689 const button = item.querySelector(".accordion-button"); 690 691 if (item.classList.contains("active")) { 692 if (content) content.style.height = content.scrollHeight + "px"; 693 if (button) button.disabled = true; 694 } else { 695 if (content) content.style.height = "0"; 696 if (button) button.disabled = false; 697 } 698 }); 699} 700 701// Attach click event handlers directly via onClick 702document.querySelectorAll(".process-style1").forEach((item) => { 703 item.onclick = () => toggleActiveItem(item); 704}); 705 706// Call initialize to set up the state 707initialize(); 708 709/*----------- 18. WOW.js Animation ----------*/ 710 var wow = new WOW({ 711 boxClass: "wow", // animated element css class (default is wow) 712 animateClass: "wow-animated", // animation css class (default is animated) 713 offset: 0, // distance to the element when triggering the animation (default is 0) 714 mobile: false, // trigger animations on mobile devices (default is true) 715 live: true, // act on asynchronously loaded content (default is true) 716 scrollContainer: null, // optional scroll container selector, otherwise use window, 717 resetAnimation: false, // reset animation on end (default is true) 718 }); 719 wow.init(); 720 721/*----------- 19. particlesJS Animation ----------*/ 722 const initParticles = (containerId) => { 723 const element = document.getElementById(containerId); 724 725 if (!element) return; 726 727 particlesJS(containerId, { 728 particles: { 729 number: { 730 value: 180, // Reduced for better performance 731 density: { enable: true, value_area: 350 }, 732 }, 733 color: { value: "#205c5e" }, 734 shape: { type: "circle", stroke: { width: 0, color: "#205c5e" } }, 735 opacity: { value: 0.1 }, 736 size: { value: 3, random: true }, 737 line_linked: { enable: true, distance: 120, color: "#205c5e", opacity: 0.6, width: 1 }, 738 move: { enable: true, speed: 1.5 }, 739 }, 740 interactivity: { 741 detect_on: "canvas", 742 events: { 743 onhover: { enable: true, mode: "grab" }, 744 onclick: { enable: true, mode: "push" }, 745 resize: true, 746 }, 747 modes: { 748 grab: { distance: 120, line_linked: { opacity: 0.8 } }, 749 }, 750 }, 751 retina_detect: true, 752 }); 753 }; 754 755// List of IDs to initialize particles 756 const ids = [ 757 "particles-js", 758 "particles-js2", 759 "particles-js4", 760 "footer-particle1", 761 "footer-particle2", 762 "faq-particle1", 763 "process-particle1", 764 "process-particle2", 765 "packag-particle1", 766 "particles-js8", 767 ]; 768 769 // Use Intersection Observer for better performance 770 const observer = new IntersectionObserver( 771 (entries) => { 772 entries.forEach((entry) => { 773 if (entry.isIntersecting) { 774 initParticles(entry.target.id); 775 observer.unobserve(entry.target); // Stop observing once initialized 776 } 777 }); 778 }, 779 { threshold: 0.1 } // Trigger when 10% of the element is visible 780 ); 781 782 ids.forEach((id) => { 783 const element = document.getElementById(id); 784 if (element) observer.observe(element); 785 }); 786 787/*----------- 20. map ----------*/ 788 const pins = document.querySelectorAll('.map .rpin'); 789 790 pins.forEach(pin => { 791 pin.onclick = () => { 792 pins.forEach(p => p.classList.remove('active')); 793 pin.classList.add('active'); 794 }; 795 }); 796 797 798 799/*----------- 21. Team active ----------*/ 800const iconButtons = document.querySelectorAll('.icon-btn'); 801 802// Assign onClick directly to each button 803iconButtons.forEach((button) => { 804 button.onclick = () => { 805 const memberLinks = button.parentElement.querySelector('.member-links'); 806 if (memberLinks) { 807 memberLinks.classList.toggle('active'); 808 } 809 }; 810}); 811 812// Assign onClick to the document for global click handling 813document.onclick = (event) => { 814 iconButtons.forEach((button) => { 815 const memberLinks = button.parentElement.querySelector('.member-links'); 816 if (memberLinks && !button.contains(event.target) && !memberLinks.contains(event.target)) { 817 memberLinks.classList.remove('active'); 818 } 819 }); 820}; 821 822 823})(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.