1// ÐÑновной JavaScript Ñайл 2document.addEventListener("DOMContentLoaded", function () { 3 // УлÑÑÑеннÑй lazy loading Ð´Ð»Ñ Ð¸Ð·Ð¾Ð±Ñажений 4 const lazyImages = document.querySelectorAll('img[loading="lazy"]'); 5 6 const imageObserver = new IntersectionObserver( 7 (entries, observer) => { 8 entries.forEach((entry) => { 9 if (entry.isIntersecting) { 10 const img = entry.target; 11 img.addEventListener("load", () => { 12 img.classList.add("loaded"); 13 }); 14 observer.unobserve(img); 15 } 16 }); 17 }, 18 { 19 rootMargin: "50px 0px", 20 threshold: 0.1, 21 } 22 ); 23 24 lazyImages.forEach((img) => { 25 imageObserver.observe(img); 26 }); 27 const searchToggles = document.querySelectorAll(".search-toggle"); 28 const mobileSearchToggle = document.querySelector(".mobile-search"); 29 const searchBlock = document.querySelector(".search"); 30 const searchClose = document.querySelector(".search__close"); 31 const searchInput = document.querySelector(".search__input"); 32 const searchSubmit = document.querySelector(".search__submit"); 33 const mobileMenu = document.querySelector(".mobile-menu"); 34 const mobileMenuClose = document.querySelector(".mobile-menu__close"); 35 const mobileSearch = document.querySelector(".mobile-search-screen"); 36 const mobileSearchBtn = document.querySelector(".mobile-menu__search-btn"); 37 const mobileSearchBack = document.querySelector(".mobile-search__back"); 38 const mobileSearchInput = document.querySelector(".mobile-search__input"); 39 const mobileSearchSubmit = document.querySelector(".mobile-search__submit"); 40 const mobileSearchResults = document.querySelector(".mobile-search__results"); 41 const desktopCatalogBtn = document.querySelector(".desktop-catalog"); 42 const catalogPanel = document.querySelector(".catalog-panel"); 43 const catalogOverlay = document.querySelector(".catalog-overlay"); 44 const catalogClose = document.querySelector(".catalog-panel__close"); 45 const mobileCatalogScreen = document.querySelector(".mobile-catalog-screen"); 46 const mobileCatalogBack = document.querySelector(".mobile-catalog__back"); 47 if (searchToggles.length && searchBlock) { 48 const openSearch = () => { 49 searchBlock.classList.add("search--open"); 50 searchBlock.setAttribute("aria-hidden", "false"); 51 if (searchInput) setTimeout(() => searchInput.focus(), 200); 52 }; 53 const closeSearch = () => { 54 searchBlock.classList.remove("search--open"); 55 searchBlock.setAttribute("aria-hidden", "true"); 56 }; 57 searchToggles.forEach((btn) => { 58 btn.addEventListener("click", openSearch); 59 }); 60 if (searchClose) searchClose.addEventListener("click", closeSearch); 61 document.addEventListener("keydown", (e) => { 62 if (e.key === "Escape") closeSearch(); 63 }); 64 } 65 66 if (searchInput && searchSubmit) { 67 let searchTimeout; 68 69 const performSearch = async (query) => { 70 if (query.length < 2) { 71 updateSearchResults([]); 72 return; 73 } 74 75 try { 76 const formData = new FormData(); 77 formData.append("action", "kvarc_search"); 78 formData.append("query", query); 79 formData.append("nonce", kvarc_ajax.nonce); 80 81 const response = await fetch(kvarc_ajax.ajax_url, { 82 method: "POST", 83 body: formData, 84 }); 85 86 const data = await response.json(); 87 88 if (data.success) { 89 updateSearchResults(data.data.results); 90 } 91 } catch (error) { 92 console.error("ÐÑибка поиÑка:", error); 93 } 94 }; 95 96 const highlightText = (text, query) => { 97 if (!query || query.length < 2) return text; 98 99 const regex = new RegExp( 100 `(${query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")})`, 101 "gi" 102 ); 103 return text.replace(regex, '<mark class="search-highlight">$1</mark>'); 104 }; 105 106 const updateSearchResults = (results) => { 107 const resultsContainer = document.querySelector(".search__results"); 108 if (!resultsContainer) { 109 return; 110 } 111 112 if (results.length === 0) { 113 resultsContainer.style.display = "none"; 114 return; 115 } 116 117 const query = searchInput.value.trim(); 118 119 // ÐÑÑппиÑÑем ÑезÑлÑÑаÑÑ Ð¿Ð¾ Ñипам 120 const products = results.filter((r) => r.type === "product"); 121 const categories = results.filter((r) => r.type === "category"); 122 const pages = results.filter((r) => r.type === "page"); 123 124 let html = ""; 125 126 // ТоваÑÑ 127 if (products.length > 0) { 128 html += 129 '<div class="search__column"><div class="search__group"><ul class="search__list">';
130 products.forEach((product) => { 131 const highlightedTitle = highlightText(product.title, query); 132 html += `<li class="search__item"><a href="${product.url}">${highlightedTitle}</a></li>`; 133 }); 134 html += "</ul></div></div>"; 135 } 136 137 // ÐаÑегоÑии 138 if (categories.length > 0) { 139 html += 140 '<div class="search__column"><div class="search__group"><ul class="search__list">'; 141 categories.forEach((category) => { 142 const highlightedTitle = highlightText(category.title, query); 143 html += `<li class="search__item"><a href="${category.url}">${highlightedTitle}</a></li>`; 144 }); 145 html += "</ul></div></div>"; 146 } 147 148 // СÑÑаниÑÑ 149 if (pages.length > 0) { 150 html += 151 '<div class="search__column"><div class="search__group"><ul class="search__list">'; 152 pages.forEach((page) => { 153 const highlightedTitle = highlightText(page.title, query); 154 html += `<li class="search__item"><a href="${page.url}">${highlightedTitle}</a></li>`; 155 }); 156 html += "</ul></div></div>"; 157 } 158 159 resultsContainer.innerHTML = html; 160 resultsContainer.style.display = "grid"; 161 }; 162 163 const updateSearchButtonState = () => { 164 const hasValue = searchInput.value.trim().length > 0; 165 searchSubmit.disabled = !hasValue; 166 167 // ÐÑиÑаем пÑедÑдÑÑий ÑаймаÑÑ 168 if (searchTimeout) { 169 clearTimeout(searchTimeout); 170 } 171 172 // УÑÑанавливаем новÑй ÑаймаÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка 173 searchTimeout = setTimeout(() => { 174 performSearch(searchInput.value.trim()); 175 }, 300); 176 }; 177 178 updateSearchButtonState(); 179 searchInput.addEventListener("input", updateSearchButtonState); 180 181 // ÐбÑабоÑка оÑпÑавки ÑоÑÐ¼Ñ 182 if (searchSubmit) { 183 searchSubmit.addEventListener("click", (e) => { 184 e.preventDefault(); 185 const query = searchInput.value.trim(); 186 if (query.length > 0) { 187 window.location.href = `${ 188 window.location.origin 189 }/?s=${encodeURIComponent(query)}`; 190 } 191 }); 192 } 193 } 194 195 const header = document.querySelector(".site-header"); 196 const openMobileMenu = () => { 197 if (!mobileMenu) return; 198 mobileMenu.classList.add("is-open"); 199 mobileMenu.setAttribute("aria-hidden", "false"); 200 if (header) header.classList.add("menu-open"); 201 document.body.style.overflow = "hidden"; 202 }; 203 const closeMobileMenu = () => { 204 if (!mobileMenu) return; 205 mobileMenu.classList.remove("is-open"); 206 mobileMenu.setAttribute("aria-hidden", "true"); 207 if (header) header.classList.remove("menu-open"); 208 document.body.style.overflow = ""; 209 }; 210 211 const burgerButtons = document.querySelectorAll(".mobile-burger"); 212 burgerButtons.forEach((btn) => 213 btn.addEventListener("click", () => { 214 const willOpen = !( 215 mobileMenu && mobileMenu.classList.contains("is-open") 216 ); 217 if (willOpen) { 218 btn.classList.add("active"); 219 openMobileMenu(); 220 } else { 221 btn.classList.remove("active"); 222 closeMobileMenu(); 223 } 224 }) 225 ); 226 227 if (mobileMenuClose) 228 mobileMenuClose.addEventListener("click", () => { 229 burgerButtons.forEach((btn) => btn.classList.remove("active")); 230 closeMobileMenu(); 231 }); 232 document.addEventListener("keydown", (e) => { 233 if (e.key === "Escape") closeMobileMenu(); 234 }); 235 236 const openMobileSearch = () => { 237 if (!mobileSearch) return; 238 mobileSearch.classList.add("is-open"); 239 mobileSearch.setAttribute("aria-hidden", "false"); 240 if (mobileSearchInput) setTimeout(() => mobileSearchInput.focus(), 150); 241 }; 242 const closeMobileSearch = () => { 243 if (!mobileSearch) return; 244 mobileSearch.classList.remove("is-open"); 245 mobileSearch.setAttribute("aria-hidden", "true"); 246 }; 247 if (mobileSearchBtn) { 248 mobileSearchBtn.addEventListener("click", openMobileSearch); 249 } else { 250 console.warn("[mobile-search] .mobile-menu__search-btn NOT FOUND at init"); 251 // делегиÑование вклÑÑаем ТÐÐЬÐРеÑли кнопка не найдена пÑи иниÑиализаÑии 252 document.addEventListener("click", (e) => { 253 const btn = 254 e.target.closest && e.target.closest(".mobile-menu__search-btn"); 255 if (btn) { 256 openMobileSearch(); 257 } 258 }); 259 } 260 if (mobileSearchBack) 261 mobileSearchBack.addEventListener("click", () => { 262 if (mobileSearchInput) mobileSearchInput.value = ""; 263 if (mobileSearchResults) mobileSearchResults.innerHTML = ""; 264 if (mobileSearchSubmit) mobileSearchSubmit.disabled = true; 265 266 // ÐÑиÑаем ÑаймаÑÑ Ð¿Ð¾Ð¸Ñка 267 if (mobileSearchTimeout) { 268 clearTimeout(mobileSearchTimeout); 269 } 270 271 closeMobileSearch(); 272 }); 273 document.addEventListener("keydown", (e) => { 274 if (e.key === "Escape") closeMobileSearch(); 275 }); 276 277 let mobileSearchTimeout; 278 279 const performMobileSearch = async (query) => { 280 if (query.length < 2) { 281 renderMobileResults([]); 282 return; 283 } 284 285 try { 286 const formData = new FormData(); 287 formData.append("action", "kvarc_search"); 288 formData.append("query", query); 289 formData.append("nonce", kvarc_ajax.nonce); 290 291 const response = await fetch(kvarc_ajax.ajax_url, { 292 method: "POST", 293 body: formData, 294 }); 295 296 const data = await response.json(); 297 298 if (data.success) { 299 renderMobileResults(data.data.results); 300 } 301 } catch (error) { 302 console.error("ÐÑибка мобилÑного поиÑка:", error); 303 } 304 }; 305 306 const renderMobileResults = (results) => { 307 if (!mobileSearchResults) return; 308 309 if (!results || results.length === 0) { 310 mobileSearchResults.innerHTML = ""; 311 return; 312 } 313 314 const html = results 315 .map( 316 (result) => 317 `<a href="${result.url}" class="mobile-search__result">
318 <span class="mobile-search__result-title">${ 319 result.title 320 }</span> 321 ${ 322 result.price 323 ? `<span class="mobile-search__result-desc">${result.price}</span>` 324 : "" 325 } 326 ${ 327 result.excerpt 328 ? `<span class="mobile-search__result-desc">${result.excerpt}</span>` 329 : "" 330 } 331 </a>` 332 ) 333 .join(""); 334 335 mobileSearchResults.innerHTML = html; 336 }; 337 338 const updateMobileSearchState = () => { 339 const hasValue = 340 !!mobileSearchInput && mobileSearchInput.value.trim().length > 0; 341 if (mobileSearchSubmit) mobileSearchSubmit.disabled = !hasValue; 342 343 // ÐÑиÑаем пÑедÑдÑÑий ÑаймаÑÑ 344 if (mobileSearchTimeout) { 345 clearTimeout(mobileSearchTimeout); 346 } 347 348 // УÑÑанавливаем новÑй ÑаймаÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка 349 mobileSearchTimeout = setTimeout(() => { 350 performMobileSearch(mobileSearchInput.value.trim()); 351 }, 300); 352 }; 353 354 if (mobileSearchInput) 355 mobileSearchInput.addEventListener("input", () => { 356 updateMobileSearchState(); 357 }); 358 if (mobileSearchSubmit) 359 mobileSearchSubmit.addEventListener("click", (e) => { 360 e.preventDefault(); 361 updateMobileSearchState(); 362 }); 363 364 const openCatalogPanel = () => { 365 if (!catalogPanel) return; 366 catalogPanel.classList.add("is-open"); 367 if (catalogOverlay) catalogOverlay.classList.add("is-open"); 368 if (header) header.classList.add("menu-open"); 369 document.body.style.overflow = "hidden"; 370 }; 371 const closeCatalogPanel = () => { 372 if (!catalogPanel) return; 373 catalogPanel.classList.remove("is-open"); 374 if (catalogOverlay) catalogOverlay.classList.remove("is-open"); 375 if (header) header.classList.remove("menu-open"); 376 document.body.style.overflow = ""; 377 }; 378 const mobileCatalogBtns = document.querySelectorAll( 379 ".mobile-catalog, .mobile-menu__catalog" 380 ); 381 382 const openMobileCatalog = () => { 383 if (!mobileCatalogScreen) return; 384 mobileCatalogScreen.classList.add("is-open"); 385 mobileCatalogScreen.setAttribute("aria-hidden", "false"); 386 if (header) header.classList.add("menu-open"); 387 document.body.style.overflow = "hidden"; 388 }; 389 const closeMobileCatalog = () => { 390 if (!mobileCatalogScreen) return; 391 mobileCatalogScreen.classList.remove("is-open"); 392 mobileCatalogScreen.setAttribute("aria-hidden", "true"); 393 if (header) header.classList.remove("menu-open"); 394 document.body.style.overflow = ""; 395 }; 396 397 if (desktopCatalogBtn) 398 desktopCatalogBtn.addEventListener("click", openCatalogPanel); 399 400 mobileCatalogBtns.forEach((btn) => { 401 // Ðнопки в mobile-actions вÑегда оÑкÑÑваÑÑ Ð´ÐµÑкÑопнÑе веÑÑии 402 if (btn.closest(".mobile-actions")) { 403 btn.addEventListener("click", openCatalogPanel); 404 } else { 405 // ÐÑÑалÑнÑе мобилÑнÑе кнопки ÑабоÑаÑÑ Ð¿Ð¾ ÑазмеÑÑ ÑкÑана 406 btn.addEventListener("click", () => { 407 if (window.innerWidth <= 768) { 408 openMobileCatalog(); 409 } else { 410 openCatalogPanel(); 411 } 412 }); 413 } 414 }); 415 416 if (mobileCatalogBack) 417 mobileCatalogBack.addEventListener("click", closeMobileCatalog); 418 if (catalogClose) catalogClose.addEventListener("click", closeCatalogPanel); 419 if (catalogOverlay) 420 catalogOverlay.addEventListener("click", closeCatalogPanel); 421 document.addEventListener("keydown", (e) => { 422 if (e.key === "Escape") { 423 closeCatalogPanel(); 424 closeMobileCatalog(); 425 } 426 }); 427 428 // ÐÐ¾Ð¿Ð°Ð¿Ñ 429 const popupOverlay = document.querySelector(".popup-overlay"); 430 const popups = document.querySelectorAll(".popup"); 431 const popupCloses = document.querySelectorAll(".popup__close"); 432 433 window.openPopup = (popupClass) => { 434 const popup = document.querySelector(`.popup-${popupClass}`); 435 if (!popup) return; 436 437 const popupOverlay = document.querySelector(".popup-overlay"); 438 popupOverlay.classList.add("is-open"); 439 popup.classList.add("is-open"); 440 document.body.style.overflow = "hidden"; 441 }; 442 443 window.closePopup = () => { 444 const popupOverlay = document.querySelector(".popup-overlay"); 445 const popups = document.querySelectorAll(".popup"); 446 popupOverlay.classList.remove("is-open"); 447 popups.forEach((popup) => popup.classList.remove("is-open")); 448 document.body.style.overflow = ""; 449 }; 450 451 // ÐакÑÑÑие попапов
452 if (popupCloses.length > 0) { 453 popupCloses.forEach((btn) => 454 btn.addEventListener("click", window.closePopup) 455 ); 456 } 457 if (popupOverlay) { 458 popupOverlay.addEventListener("click", window.closePopup); 459 } 460 document.addEventListener("keydown", (e) => { 461 if (e.key === "Escape") window.closePopup(); 462 }); 463 464 // Ðогика гоÑода 465 const cityConfirm = document.querySelector(".popup-city-confirm"); 466 const cityChange = document.querySelector(".popup-city-change"); 467 const cityItems = document.querySelectorAll(".popup__city-item"); 468 const locationBtn = document.querySelector(".location__btn"); 469 const cityNameDisplay = document.querySelector(".popup__city-name"); 470 const citySearchInput = document.querySelector(".popup__search-input"); 471 const citiesList = document.querySelector(".popup__cities-list"); 472 473 if (cityConfirm) { 474 cityConfirm.addEventListener("click", () => { 475 const currentCity = cityNameDisplay 476 ? cityNameDisplay.textContent 477 : "ÐÐÐ ÐÐÐÐ"; 478 localStorage.setItem("cityConfirmed", "true"); 479 localStorage.setItem("userCity", currentCity.toLowerCase()); 480 if (locationBtn) locationBtn.textContent = currentCity.toLowerCase(); 481 window.closePopup(); 482 }); 483 } 484 485 cityItems.forEach((item) => { 486 item.addEventListener("click", (e) => { 487 // ÐÑли ÑÑо ÑÑÑлка на дÑÑгой гоÑод, не пеÑÐµÑ Ð²Ð°ÑÑваем ÑобÑÑие 488 if (item.tagName === "A" && item.href) { 489 // ÐÑиÑаем localStorage пеÑед пеÑÐµÑ Ð¾Ð´Ð¾Ð¼ 490 localStorage.removeItem("city_popup_shown"); 491 localStorage.removeItem("user_city_confirmed"); 492 return; // ÐозволÑем бÑаÑзеÑÑ Ð¿ÐµÑейÑи по ÑÑÑлке 493 } 494 495 // ÐÐ»Ñ ÐºÐ½Ð¾Ð¿Ð¾Ðº (ÑÑаÑÐ°Ñ Ð»Ð¾Ð³Ð¸ÐºÐ°) 496 const city = item.dataset.city; 497 localStorage.setItem("cityConfirmed", "true"); 498 localStorage.setItem("userCity", city); 499 if (locationBtn) locationBtn.textContent = city; 500 if (cityNameDisplay) cityNameDisplay.textContent = city.toUpperCase(); 501 window.closePopup(); 502 }); 503 }); 504 505 506 // ÐоиÑк гоÑодов 507 if (citySearchInput && citiesList) { 508 const allCityItems = [...cityItems]; 509 510 citySearchInput.addEventListener("input", (e) => { 511 const searchTerm = e.target.value.toLowerCase().trim(); 512 513 allCityItems.forEach((item) => { 514 const cityName = item.textContent.toLowerCase(); 515 const isVisible = cityName.includes(searchTerm); 516 item.style.display = isVisible ? "block" : "none"; 517 }); 518 519 // ÐоказÑваем ÑообÑение еÑли ниÑего не найдено 520 const visibleItems = allCityItems.filter( 521 (item) => item.style.display !== "none" 522 ); 523 if (visibleItems.length === 0 && searchTerm) { 524 if (!citiesList.querySelector(".popup__no-results")) { 525 const noResults = document.createElement("div"); 526 noResults.className = "popup__no-results"; 527 noResults.textContent = "ÐоÑод не найден"; 528 citiesList.appendChild(noResults); 529 } 530 } else { 531 const noResults = citiesList.querySelector(".popup__no-results"); 532 if (noResults) noResults.remove(); 533 } 534 }); 535 536 // ÐÑиÑаем поиÑк пÑи оÑкÑÑÑии попапа гоÑодов 537 const citiesPopup = document.querySelector(".popup-cities"); 538 if (citiesPopup) { 539 const observer = new MutationObserver((mutations) => { 540 mutations.forEach((mutation) => { 541 if ( 542 mutation.type === "attributes" && 543 mutation.attributeName === "class" 544 ) { 545 if (citiesPopup.classList.contains("is-open")) { 546 setTimeout(() => { 547 citySearchInput.value = ""; 548 allCityItems.forEach((item) => (item.style.display = "block")); 549 const noResults = 550 citiesList.querySelector(".popup__no-results"); 551 if (noResults) noResults.remove(); 552 citySearchInput.focus(); 553 }, 100); 554 } 555 } 556 }); 557 }); 558 observer.observe(citiesPopup, { attributes: true }); 559 } 560 } 561 562 // Ðнопки оÑкÑÑÑÐ¸Ñ Ð¿Ð¾Ð¿Ð°Ð¿Ð¾Ð² 563 const authLinks = document.querySelectorAll('[href="#"]'); 564 const orderBtn = document.querySelector(".hero__btn"); 565 566 if (orderBtn) { 567 orderBtn.addEventListener("click", (e) => { 568 e.preventDefault(); 569 openPopup("request"); 570 }); 571 } 572 573 // ÐвÑоÑизаÑÐ¸Ñ 574 const authToggle = document.querySelector(".auth-toggle"); 575 if (authToggle) { 576 authToggle.addEventListener("click", (e) => { 577 e.preventDefault(); 578 openPopup("auth"); 579 }); 580 } 581 582 // СÑаÑÐ°Ñ Ð»Ð¾Ð³Ð¸ÐºÐ° Ð´Ð»Ñ Ð¾Ð±ÑаÑной ÑовмеÑÑимоÑÑи 583 authLinks.forEach((link) => { 584 if (link.closest(".icon-link") && link.querySelector('img[src*="exit"]')) { 585 link.addEventListener("click", (e) => { 586 e.preventDefault(); 587 openPopup("auth"); 588 }); 589 } 590 }); 591 592 // Ð¢Ð°Ð±Ñ Ð°Ð²ÑоÑизаÑии 593 const authTabs = document.querySelectorAll(".popup__tab"); 594 const authContents = document.querySelectorAll(".popup__tab-content"); 595
596 authTabs.forEach((tab) => { 597 tab.addEventListener("click", () => { 598 const targetTab = tab.dataset.tab; 599 600 authTabs.forEach((t) => t.classList.remove("popup__tab--active")); 601 authContents.forEach((c) => 602 c.classList.remove("popup__tab-content--active") 603 ); 604 605 tab.classList.add("popup__tab--active"); 606 document 607 .querySelector(`[data-content="${targetTab}"]`) 608 .classList.add("popup__tab-content--active"); 609 }); 610 }); 611 612 // ÐалидаÑÐ¸Ñ ÑоÑм и ÑпÑавление кнопками 613 const forms = document.querySelectorAll(".popup__form"); 614 615 const validateForm = (form) => { 616 const submitBtn = form.querySelector(".popup__submit"); 617 const requiredInputs = form.querySelectorAll( 618 "input[required], textarea[required]" 619 ); 620 const requiredCheckboxes = form.querySelectorAll( 621 'input[type="checkbox"][required]' 622 ); 623 624 let isValid = true; 625 626 // ÐÑовеÑÑем обÑзаÑелÑнÑе Ð¿Ð¾Ð»Ñ 627 requiredInputs.forEach((input) => { 628 if (!input.value.trim()) { 629 isValid = false; 630 } 631 }); 632 633 // ÐÑовеÑÑем обÑзаÑелÑнÑе ÑекбокÑÑ 634 requiredCheckboxes.forEach((checkbox) => { 635 if (!checkbox.checked) { 636 isValid = false; 637 } 638 }); 639 640 // УпÑавлÑем ÑоÑÑоÑнием кнопки 641 if (submitBtn) { 642 submitBtn.disabled = !isValid; 643 if (isValid) { 644 submitBtn.classList.remove("popup__submit--disabled"); 645 } else { 646 submitBtn.classList.add("popup__submit--disabled"); 647 } 648 } 649 }; 650 651 forms.forEach((form) => { 652 const inputs = form.querySelectorAll("input, textarea"); 653 const checkboxes = form.querySelectorAll('input[type="checkbox"]'); 654 655 // ÐзнаÑалÑно валидиÑÑем ÑоÑÐ¼Ñ 656 validateForm(form); 657 658 // СлÑÑаем Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² полÑÑ Ð²Ð²Ð¾Ð´Ð° 659 inputs.forEach((input) => { 660 input.addEventListener("input", () => validateForm(form)); 661 input.addEventListener("change", () => validateForm(form)); 662 }); 663 664 // СлÑÑаем Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² ÑекбокÑÐ°Ñ 665 checkboxes.forEach((checkbox) => { 666 checkbox.addEventListener("change", () => validateForm(form)); 667 }); 668 669 // ÐбÑабоÑка оÑпÑавки 670 form.addEventListener("submit", (e) => { 671 e.preventDefault(); 672 validateForm(form); 673 674 const submitBtn = form.querySelector(".popup__submit"); 675 if (submitBtn && !submitBtn.disabled) { 676 // ÐдеÑÑ Ð±ÑÐ´ÐµÑ Ð»Ð¾Ð³Ð¸ÐºÐ° оÑпÑавки 677 window.closePopup(); 678 } 679 }); 680 }); 681 682 // ÐниÑиализаÑÐ¸Ñ Swiper ÑлайдеÑа Ð´Ð»Ñ ÐºÐ°ÑегоÑий 683 if (document.querySelector(".categories__slider")) { 684 var swiper = new Swiper(".categories__slider", { 685 slidesPerView: 4, 686 slidesPerColumn: 2, 687 spaceBetween: 15, 688 slidesPerColumnFill: "row", 689 navigation: { 690 nextEl: ".categories__arrow--next", 691 prevEl: ".categories__arrow--prev", 692 }, 693 scrollbar: { 694 el: ".categories__scrollbar", 695 draggable: true, 696 }, 697 }); 698 } 699 700 // СÑÑаниÑа ÑоваÑа 701 const tabBtns = document.querySelectorAll(".tab-btn"); 702 const tabContents = document.querySelectorAll(".tab-content"); 703 704 tabBtns.forEach((btn) => { 705 btn.addEventListener("click", () => { 706 const targetTab = btn.dataset.tab; 707 708 tabBtns.forEach((b) => b.classList.remove("tab-btn--active")); 709 tabContents.forEach((c) => c.classList.remove("tab-content--active")); 710 711 btn.classList.add("tab-btn--active"); 712 document.getElementById(targetTab).classList.add("tab-content--active"); 713 }); 714 }); 715 716 const quantityBtns = document.querySelectorAll(".quantity-btn"); 717 const quantityInput = document.querySelector(".quantity-input"); 718 719 quantityBtns.forEach((btn) => { 720 btn.addEventListener("click", () => { 721 if (!quantityInput) return; 722 723 let value = parseInt(quantityInput.value) || 1; 724 725 if (btn.classList.contains("quantity-btn--minus")) { 726 value = Math.max(1, value - 1); 727 } else if (btn.classList.contains("quantity-btn--plus")) { 728 value = value + 1; 729 } 730 731 quantityInput.value = value; 732 }); 733 }); 734 735 const galleryMain = document.querySelector(".product-gallery__main"); 736 const galleryThumbs = document.querySelector(".product-gallery__thumbs"); 737 738 if (galleryMain && galleryThumbs) { 739 var thumbsSwiper = new Swiper(galleryThumbs, { 740 spaceBetween: 12, 741 slidesPerView: 3, 742 watchSlidesProgress: true, 743 breakpoints: { 744 320: { 745 slidesPerView: 2, 746 spaceBetween: 8, 747 }, 748 768: { 749 slidesPerView: 3, 750 spaceBetween: 12, 751 }, 752 1024: { 753 slidesPerView: 3, 754 spaceBetween: 12, 755 }, 756 }, 757 }); 758 759 var mainSwiper = new Swiper(galleryMain, { 760 spaceBetween: 10, 761 slidesPerView: 1, 762 navigation: { 763 nextEl: ".swiper-button-next", 764 prevEl: ".swiper-button-prev", 765 }, 766 scrollbar: { 767 el: ".swiper-scrollbar", 768 draggable: true, 769 }, 770 thumbs: { 771 swiper: thumbsSwiper, 772 }, 773 }); 774 775 // Ð ÑÑÐ½Ð°Ñ Ð¿ÑивÑзка кликов по миниаÑÑÑам 776 galleryThumbs.querySelectorAll('.swiper-slide').forEach(function(thumb, index) { 777 thumb.style.cursor = 'pointer'; 778 thumb.addEventListener('click', function() { 779 mainSwiper.slideTo(index); 780 }); 781 }); 782 783 // ÐодÑвеÑка акÑивной миниаÑÑÑÑ Ð¿Ñи Ñмене Ñлайда 784 mainSwiper.on('slideChange', function() { 785 var activeIndex = mainSwiper.activeIndex; 786 galleryThumbs.querySelectorAll('.swiper-slide').forEach(function(t, i) { 787 t.classList.toggle('swiper-slide-thumb-active', i === activeIndex); 788 }); 789 }); 790 } 791 792 // Ð¡Ð»Ð°Ð¹Ð´ÐµÑ Ð»Ð¸Ð´ÐµÑÑ Ð¿Ñодаж 793 const bestsellersSlider = document.querySelector(".bestsellers__slider"); 794 if (bestsellersSlider) { 795 const bestsellersSwiper = new Swiper(bestsellersSlider, { 796 slidesPerView: 4, 797 spaceBetween: 24, 798 navigation: { 799 nextEl: ".bestsellers__arrow--next", 800 prevEl: ".bestsellers__arrow--prev", 801 }, 802 scrollbar: { 803 el: ".bestsellers__slider .swiper-scrollbar", 804 draggable: true, 805 }, 806 breakpoints: { 807 320: { 808 slidesPerView: 1.2, 809 spaceBetween: 16, 810 }, 811 768: { 812 slidesPerView: 1.2, 813 spaceBetween: 20, 814 }, 815 900: { 816 slidesPerView: 3, 817 spaceBetween: 24, 818 }, 819 1200: { 820 slidesPerView: 4, 821 spaceBetween: 24, 822 }, 823 }, 824 }); 825 } 826 827 // ÐÐ¸Ð¿ÐºÐ°Ñ Ð¿Ð°Ð½ÐµÐ»Ñ ÑоваÑа 828 const productSticky = document.getElementById("productSticky"); 829 if (productSticky) { 830 let lastScrollY = 0; 831 832 const handleScroll = () => { 833 const scrollY = window.scrollY; 834 const productInfo = document.querySelector(".product-info"); 835 836 if (productInfo) { 837 const productInfoBottom = 838 productInfo.offsetTop + productInfo.offsetHeight; 839 840 // ÐоказÑваем Ð¿Ð°Ð½ÐµÐ»Ñ ÐºÐ¾Ð³Ð´Ð° пÑокÑÑÑили ниже оÑновной инÑоÑмаÑии о ÑоваÑе 841 if (scrollY > productInfoBottom) { 842 productSticky.classList.add("show"); 843 } else { 844 productSticky.classList.remove("show"); 845 } 846 } 847 848 lastScrollY = scrollY; 849 }; 850 851 window.addEventListener("scroll", handleScroll, { passive: true }); 852 853 // Ð¡Ð¸Ð½Ñ ÑонизаÑÐ¸Ñ ÐºÐ¾Ð»Ð¸ÑеÑÑва Ñ Ð¾Ñновной ÑоÑмой 854 const stickyQuantityBtns = productSticky.querySelectorAll(".quantity-btn"); 855 const stickyQuantityInput = productSticky.querySelector(".quantity-input"); 856 const mainQuantityInput = document.querySelector( 857 ".product-purchase .quantity-input" 858 ); 859 860 stickyQuantityBtns.forEach((btn) => { 861 btn.addEventListener("click", () => { 862 if (!stickyQuantityInput) return; 863 864 let value = parseInt(stickyQuantityInput.value) || 1; 865 866 if (btn.classList.contains("quantity-btn--minus")) { 867 value = Math.max(1, value - 1); 868 } else if (btn.classList.contains("quantity-btn--plus")) { 869 value = value + 1; 870 } 871 872 stickyQuantityInput.value = value; 873 if (mainQuantityInput) mainQuantityInput.value = value; 874 }); 875 }); 876 877 // Ð¡Ð¸Ð½Ñ ÑонизаÑÐ¸Ñ Ð¿Ñи изменении в оÑновной ÑоÑме 878 if (mainQuantityInput && stickyQuantityInput) { 879 mainQuantityInput.addEventListener("input", () => { 880 stickyQuantityInput.value = mainQuantityInput.value; 881 }); 882 } 883 } 884 885 const favoriteBtn = document.querySelector(".product-info__favorite"); 886 if (favoriteBtn) { 887 favoriteBtn.addEventListener("click", () => { 888 favoriteBtn.classList.toggle("product-info__favorite--active"); 889 }); 890 } 891 892 const addToCartBtn = document.querySelector(".btn--cart"); 893 if (addToCartBtn) { 894 addToCartBtn.addEventListener("click", () => { 895 const quantity = quantityInput ? parseInt(quantityInput.value) || 1 : 1; 896 }); 897 } 898 899 900 901 902 903 904 905 // Ð¡Ð¸Ð½Ñ ÑонизаÑÐ¸Ñ Ñ WooCommerce пÑи загÑÑзке ÑÑÑаниÑÑ 906 const variationsForm = document.querySelector(".variations_form"); 907 if (variationsForm) { 908 // ÐниÑиализиÑÑем WooCommerce ваÑиаÑии 909 if (typeof wc_add_to_cart_variation_params !== "undefined") { 910 // WooCommerce Ñже иниÑиализиÑован 911 } else { 912 // Ðдем иниÑиализаÑии WooCommerce 913 setTimeout(() => { 914 const event = new Event("wc_variation_form", { bubbles: true }); 915 variationsForm.dispatchEvent(event); 916 }, 100); 917 } 918 } 919 920 // Video Swiper 921 const videoSwiper = new Swiper(".video-slider", { 922 slidesPerView: 1.2, 923 spaceBetween: 20, 924 navigation: { 925 nextEl: ".video-btn-next", 926 prevEl: ".video-btn-prev", 927 }, 928 breakpoints: { 929 320: { 930 slidesPerView: 1, 931 spaceBetween: 16, 932 }, 933 768: { 934 slidesPerView: 1, 935 spaceBetween: 10, 936 }, 937 1024: { 938 spaceBetween: 20, 939 slidesPerView: 1.2, 940 }, 941 }, 942 }); 943 944 // Production Slider
945 const productionSwiper = new Swiper(".production-slider", { 946 effect: "fade", 947 fadeEffect: { 948 crossFade: true, 949 }, 950 slidesPerView: 1, 951 952 pagination: { 953 el: ".swiper-pagination", 954 clickable: true, 955 }, 956 navigation: { 957 nextEl: ".swiper-button-next", 958 prevEl: ".swiper-button-prev", 959 }, 960 }); 961 962 // ЯкоÑÐ½Ð°Ñ Ð½Ð°Ð²Ð¸Ð³Ð°ÑÐ¸Ñ Ð´Ð»Ñ ÑÑÑаниÑÑ Ð ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ð¸ 963 const aboutNavLinks = document.querySelectorAll(".about-nav__link"); 964 const aboutSections = document.querySelectorAll(".about-section"); 965 966 if (aboutNavLinks.length > 0) { 967 // Smooth scroll Ð´Ð»Ñ ÑкоÑнÑÑ ÑÑÑлок 968 aboutNavLinks.forEach((link) => { 969 link.addEventListener("click", (e) => { 970 e.preventDefault(); 971 const targetId = link.getAttribute("href").substring(1); 972 const targetSection = document.getElementById(targetId); 973 974 if (targetSection) { 975 targetSection.scrollIntoView({ 976 behavior: "smooth", 977 block: "start", 978 }); 979 980 // ÐбновлÑем акÑивнÑÑ ÑÑÑÐ»ÐºÑ 981 aboutNavLinks.forEach((l) => l.classList.remove("active")); 982 link.classList.add("active"); 983 } 984 }); 985 }); 986 987 // ÐÑÑлеживание ÑкÑолла Ð´Ð»Ñ Ð°ÐºÑиваÑии ÑÑÑлок 988 const handleAboutScroll = () => { 989 let current = ""; 990 991 aboutSections.forEach((section) => { 992 const sectionTop = section.offsetTop - 120; 993 const sectionHeight = section.offsetHeight; 994 995 if ( 996 window.scrollY >= sectionTop && 997 window.scrollY < sectionTop + sectionHeight 998 ) { 999 current = section.getAttribute("id"); 1000 } 1001 }); 1002 1003 if (current) { 1004 aboutNavLinks.forEach((link) => { 1005 link.classList.remove("active"); 1006 if (link.getAttribute("href") === `#${current}`) { 1007 link.classList.add("active"); 1008 } 1009 }); 1010 } 1011 }; 1012 1013 window.addEventListener("scroll", handleAboutScroll, { passive: true }); 1014 } 1015 1016 // ÐпÑеделение гоÑода полÑзоваÑÐµÐ»Ñ 1017 function detectUserCity() { 1018 // ÐÑовеÑÑем, показÑвали ли Ð¼Ñ Ñже попап в ÑÑой ÑеÑÑии 1019 const cityPopupShown = localStorage.getItem("city_popup_shown"); 1020 if (cityPopupShown) { 1021 return; 1022 } 1023 1024 if (typeof kvarc_ajax !== "undefined") { 1025 fetch(kvarc_ajax.ajax_url, { 1026 method: "POST", 1027 headers: { 1028 "Content-Type": "application/x-www-form-urlencoded", 1029 }, 1030 body: "action=get_user_city&nonce=" + kvarc_ajax.nonce, 1031 }) 1032 .then((response) => response.json()) 1033 .then((data) => { 1034 if (data.success && data.data.show_popup) { 1035 showCityPopup(data.data.city); 1036 // Ð¡Ð¾Ñ ÑанÑем, ÑÑо попап Ñже показан 1037 localStorage.setItem("city_popup_shown", "true"); 1038 } 1039 }) 1040 .catch((error) => {}); 1041 } 1042 } 1043 1044 // Ðаппинг английÑÐºÐ¸Ñ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ð¹ гоÑодов на ÑÑÑÑкие 1045 const cityMapping = { 1046 TOLYATTI: "ТÐÐЬЯТТÐ", 1047 MOSCOW: "ÐÐСÐÐÐ", 1048 "SAINT PETERSBURG": "СÐÐÐТ-ÐÐТÐÐ ÐУРÐ", 1049 SPB: "СÐÐÐТ-ÐÐТÐÐ ÐУРÐ", 1050 NOVOSIBIRSK: "ÐÐÐÐСÐÐÐРСÐ", 1051 EKATERINBURG: "ÐÐÐТÐÐ ÐÐÐУРÐ", 1052 KAZAN: "ÐÐÐÐÐЬ", 1053 "NIZHNY NOVGOROD": "ÐÐÐÐÐÐ ÐÐÐÐÐÐ ÐÐ", 1054 CHELYABINSK: "ЧÐÐЯÐÐÐСÐ", 1055 SAMARA: "СÐÐÐÐ Ð", 1056 ROSTOV: "Ð ÐСТÐÐ-ÐÐ-ÐÐÐУ", 1057 "ROSTOV-ON-DON": "Ð ÐСТÐÐ-ÐÐ-ÐÐÐУ", 1058 UFA: "УФÐ", 1059 KRASNOYARSK: "ÐÐ ÐСÐÐЯРСÐ", 1060 PERM: "ÐÐÐ ÐЬ", 1061 VORONEZH: "ÐÐÐ ÐÐÐÐ", 1062 VOLGOGRAD: "ÐÐÐÐÐÐÐ ÐÐ", 1063 KRASNODAR: "ÐÐ ÐСÐÐÐÐÐ ", 1064 SARATOV: "СÐÐ ÐТÐÐ", 1065 TYUMEN: "ТЮÐÐÐЬ", 1066 IZHEVSK: "ÐÐÐÐСÐ", 1067 BARNAUL: "ÐÐÐ ÐÐУÐ", 1068 ULYANOVSK: "УÐЬЯÐÐÐСÐ", 1069 IRKUTSK: "ÐÐ ÐУТСÐ", 1070 KHABAROVSK: "Ð¥ÐÐÐÐ ÐÐСÐ", 1071 YAROSLAVL: "ЯРÐСÐÐÐÐЬ", 1072 VLADIVOSTOK: "ÐÐÐÐÐÐÐСТÐÐ", 1073 MAKHACHKALA: "ÐÐÐ¥ÐЧÐÐÐÐ", 1074 TOMSK: "ТÐÐСÐ", 1075 ORENBURG: "ÐÐ ÐÐÐУРÐ", 1076 KEMEROVO: "ÐÐÐÐÐ ÐÐÐ", 1077 RYAZAN: "РЯÐÐÐЬ", 1078 ASTRAKHAN: "ÐСТРÐÐ¥ÐÐЬ", 1079 "NABEREZHNYE CHELNY": "ÐÐÐÐÐ ÐÐÐЫРЧÐÐÐЫ", 1080 PENZA: "ÐÐÐÐÐ", 1081 LIPETSK: "ÐÐÐÐЦÐ", 1082 KIROV: "ÐÐÐ ÐÐ", 1083 CHEBOKSARY: "ЧÐÐÐÐСÐРЫ", 1084 TULA: "ТУÐÐ", 1085 KALININGRAD: "ÐÐÐÐÐÐÐÐÐ ÐÐ", 1086 BRYANSK: "ÐРЯÐСÐ", 1087 IVANOVO: "ÐÐÐÐÐÐÐ", 1088 MAGNITOGORSK: "ÐÐÐÐÐТÐÐÐРСÐ", 1089 KURSK: "ÐУРСÐ", 1090 ARKHANGELSK: "ÐРХÐÐÐÐÐЬСÐ", 1091 TVER: "ТÐÐРЬ", 1092 STAVROPOL: "СТÐÐÐ ÐÐÐÐЬ", 1093 SIMFEROPOL: "СÐÐФÐÐ ÐÐÐÐЬ", 1094 BELGOROD: "ÐÐÐÐÐÐ ÐÐ", 1095 SOCHI: "СÐЧÐ", 1096 VLADIMIR: "ÐÐÐÐÐÐÐÐ ", 1097 CHITA: "ЧÐТÐ", 1098 GROZNY: "ÐÐ ÐÐÐЫÐ", 1099 KALUGA: "ÐÐÐУÐÐ", 1100 SMOLENSK: "СÐÐÐÐÐСÐ", 1101 VOLZHESK: "ÐÐÐÐСÐ", 1102 Cherepovets: "ЧÐÐ ÐÐÐÐÐЦ", 1103 Vladikavkaz: "ÐÐÐÐÐÐÐÐÐÐÐ", 1104 Saransk: "СÐÐ ÐÐСÐ", 1105 Yakutsk: "ЯÐУТСÐ", 1106 Murmansk: "ÐУРÐÐÐСÐ", 1107 Vladimir: "ÐÐÐÐÐÐÐÐ ", 1108 Orenburg: "ÐÐ ÐÐÐУРÐ", 1109 Novokuznetsk: "ÐÐÐÐÐУÐÐÐЦÐ", 1110 Kirov: "ÐÐÐ ÐÐ", 1111 Cheboksary: "ЧÐÐÐÐСÐРЫ", 1112 Ivanovo: "ÐÐÐÐÐÐÐ", 1113 Magnitogorsk: "ÐÐÐÐÐТÐÐÐРСÐ", 1114 Krasnodar: "ÐÐ ÐСÐÐÐÐÐ ", 1115 Tula: "ТУÐÐ", 1116 Bryansk: "ÐРЯÐСÐ", 1117 Sochi: "СÐЧÐ", 1118 Arkhangelsk: "ÐРХÐÐÐÐÐЬСÐ", 1119 Stavropol: "СТÐÐÐ ÐÐÐÐЬ", 1120 Kaluga: "ÐÐÐУÐÐ", 1121 Smolensk: "СÐÐÐÐÐСÐ", 1122 Volzhsk: "ÐÐÐÐСÐ", 1123 Vladikavkaz: "ÐÐÐÐÐÐÐÐÐÐÐ", 1124 Saransk: "СÐÐ ÐÐСÐ", 1125 Yakutsk: "ЯÐУТСÐ", 1126 Murmansk: "ÐУРÐÐÐСÐ", 1127 Novokuznetsk: "ÐÐÐÐÐУÐÐÐЦÐ", 1128 }; 1129 1130 function translateCityName(cityName) { 1131 const upperCity = cityName.toUpperCase(); 1132 return cityMapping[upperCity] || cityName.toUpperCase(); 1133 } 1134 1135 function showCityPopup(cityName) { 1136 const popupCity = document.querySelector(".popup-city"); 1137 const popupOverlay = document.querySelector(".popup-overlay"); 1138 const cityNameElement = document.querySelector(".popup__city-name"); 1139 const confirmBtn = document.querySelector(".popup-city-confirm"); 1140 const changeBtn = document.querySelector(".popup-city-change"); 1141 1142 if (popupCity && popupOverlay && cityNameElement) { 1143 cityNameElement.textContent = translateCityName(cityName); 1144 1145 // ÐоказÑваем попап 1146 popupCity.classList.add("is-open"); 1147 popupOverlay.classList.add("is-open"); 1148 1149 // ÐбÑабоÑÑик Ð´Ð»Ñ ÐºÐ½Ð¾Ð¿ÐºÐ¸ "Ðа, ÑпаÑибо" 1150 if (confirmBtn) { 1151 // УдалÑем ÑÑаÑÑе обÑабоÑÑики 1152 const newConfirmBtn = confirmBtn.cloneNode(true); 1153 confirmBtn.parentNode.replaceChild(newConfirmBtn, confirmBtn); 1154 1155 newConfirmBtn.addEventListener("click", () => { 1156 // Ð¡Ð¾Ñ ÑанÑем вÑÐ±Ð¾Ñ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ 1157 localStorage.setItem("city_popup_shown", "true"); 1158 localStorage.setItem("user_city_confirmed", cityName); 1159 1160 // ÐакÑÑваем попап 1161 popupCity.classList.remove("is-open"); 1162 popupOverlay.classList.remove("is-open"); 1163 }); 1164 } 1165 1166 // ÐбÑабоÑÑик Ð´Ð»Ñ ÐºÐ½Ð¾Ð¿ÐºÐ¸ "ÐеÑ, дÑÑгой" 1167 if (changeBtn) { 1168 // УдалÑем ÑÑаÑÑе обÑабоÑÑики 1169 const newChangeBtn = changeBtn.cloneNode(true); 1170 changeBtn.parentNode.replaceChild(newChangeBtn, changeBtn); 1171 1172 newChangeBtn.addEventListener("click", (e) => { 1173 e.preventDefault(); 1174 popupCity.classList.remove("is-open"); 1175 1176 // ÐÑиÑаем ÑÐ¾Ñ ÑаненнÑй вÑбоÑ, Ñак как полÑзоваÑÐµÐ»Ñ Ñ Ð¾ÑÐµÑ Ð²ÑбÑаÑÑ Ð´ÑÑгой гоÑод 1177 localStorage.removeItem("city_popup_shown"); 1178 localStorage.removeItem("user_city_confirmed"); 1179 1180 }); 1181 } 1182 } 1183 } 1184 1185 1186 // ÐбÑабоÑÑики закÑÑÑÐ¸Ñ Ð¿Ð¾Ð¿Ð°Ð¿Ð¾Ð² 1187 const popupCloseButtons = document.querySelectorAll(".popup__close"); 1188 popupCloseButtons.forEach((closeBtn) => { 1189 closeBtn.addEventListener("click", () => { 1190 const popup = closeBtn.closest(".popup");
1191 const overlay = document.querySelector(".popup-overlay"); 1192 1193 if (popup) { 1194 popup.classList.remove("is-open"); 1195 } 1196 if (overlay) { 1197 overlay.classList.remove("is-open"); 1198 } 1199 }); 1200 }); 1201 1202 // ÐÑиÑаем localStorage пÑи вÑбоÑе гоÑода из ÑпиÑка (пеÑÐµÑ Ð¾Ð´ на дÑÑгой ÑайÑ) 1203 const cityLinks = document.querySelectorAll( 1204 ".footer__cities a, .popup__city-item[href]" 1205 ); 1206 cityLinks.forEach((link) => { 1207 link.addEventListener("click", () => { 1208 localStorage.removeItem("city_popup_shown"); 1209 localStorage.removeItem("user_city_confirmed"); 1210 }); 1211 }); 1212 1213 // УпÑавление ÑоÑÑоÑнием кнопок CF7 ÑоÑм 1214 const cf7Forms = document.querySelectorAll(".wpcf7-form"); 1215 1216 cf7Forms.forEach((form) => { 1217 const submitBtn = form.querySelector(".wpcf7-submit"); 1218 1219 const validateCF7Form = () => { 1220 let isValid = true; 1221 1222 // ÐÑовеÑÑем обÑзаÑелÑнÑе Ð¿Ð¾Ð»Ñ Ð²Ð²Ð¾Ð´Ð° (иÑклÑÑÐ°Ñ ÑекбокÑÑ) 1223 const requiredInputs = form.querySelectorAll( 1224 ".wpcf7-validates-as-required:not(.wpcf7-checkbox)" 1225 ); 1226 requiredInputs.forEach((input) => { 1227 if (!input.value.trim()) { 1228 isValid = false; 1229 } 1230 }); 1231 1232 // ÐÑовеÑÑем обÑзаÑелÑнÑе ÑекбокÑÑ 1233 const requiredCheckboxes = form.querySelectorAll( 1234 'input[type="checkbox"][required]' 1235 ); 1236 requiredCheckboxes.forEach((checkbox) => { 1237 if (!checkbox.checked) { 1238 isValid = false; 1239 } 1240 }); 1241 1242 // ÐÑовеÑÑем CF7 acceptance ÑекбокÑÑ 1243 const acceptanceCheckboxes = form.querySelectorAll( 1244 '.wpcf7-acceptance input[type="checkbox"]' 1245 ); 1246 acceptanceCheckboxes.forEach((checkbox) => { 1247 if (!checkbox.checked) { 1248 isValid = false; 1249 } 1250 }); 1251 1252 // УпÑавлÑем ÑоÑÑоÑнием кнопки 1253 if (submitBtn) { 1254 submitBtn.disabled = !isValid; 1255 if (isValid) { 1256 submitBtn.classList.remove("disabled"); 1257 } else { 1258 submitBtn.classList.add("disabled"); 1259 } 1260 } 1261 }; 1262 1263 // ÐзнаÑалÑно валидиÑÑем ÑоÑÐ¼Ñ 1264 validateCF7Form(); 1265 1266 // СлÑÑаем Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² полÑÑ Ð²Ð²Ð¾Ð´Ð° 1267 const textInputs = form.querySelectorAll( 1268 'input[type="text"], input[type="tel"], input[type="email"], textarea' 1269 ); 1270 textInputs.forEach((input) => { 1271 input.addEventListener("input", validateCF7Form); 1272 input.addEventListener("change", validateCF7Form); 1273 }); 1274 1275 // СлÑÑаем Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² ÑекбокÑÐ°Ñ 1276 const checkboxes = form.querySelectorAll('input[type="checkbox"]'); 1277 checkboxes.forEach((checkbox) => { 1278 checkbox.addEventListener("change", validateCF7Form); 1279 }); 1280 1281 // СлÑÑаем Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² CF7 acceptance ÑекбокÑÐ°Ñ 1282 const acceptanceCheckboxes = form.querySelectorAll( 1283 '.wpcf7-acceptance input[type="checkbox"]' 1284 ); 1285 acceptanceCheckboxes.forEach((checkbox) => { 1286 checkbox.addEventListener("change", validateCF7Form); 1287 }); 1288 1289 // ÐбÑабоÑÑик Ð´Ð»Ñ ÐºÐ°ÑÑомнÑÑ ÑекбокÑов 1290 const customCheckboxes = form.querySelectorAll(".popup__checkbox"); 1291 customCheckboxes.forEach((customCheckbox) => { 1292 const checkbox = customCheckbox.querySelector('input[type="checkbox"]'); 1293 if (checkbox) { 1294 // СлÑÑаем Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÑекбокÑа 1295 checkbox.addEventListener("change", () => { 1296 // ÐобавлÑем/ÑбиÑаем клаÑÑ Ð´Ð»Ñ ÑÑилизаÑии 1297 customCheckbox.classList.toggle( 1298 "popup__checkbox--checked", 1299 checkbox.checked 1300 ); 1301 validateCF7Form(); 1302 }); 1303 1304 // ÐзнаÑалÑно ÑÑÑанавливаем ÑÑÐ¸Ð»Ñ 1305 customCheckbox.classList.toggle( 1306 "popup__checkbox--checked", 1307 checkbox.checked 1308 ); 1309 } 1310 }); 1311 }); 1312 1313 // AJAX логин и ÑегиÑÑÑаÑÐ¸Ñ 1314 const loginForm = document.querySelector("#login-form"); 1315 const registerForm = document.querySelector("#register-form"); 1316 const logoutBtn = document.querySelector("#logout-btn"); 1317 1318 if (loginForm) { 1319 loginForm.addEventListener("submit", function (e) { 1320 e.preventDefault(); 1321 1322 const formData = new FormData(); 1323 formData.append("action", "kvarc_login"); 1324 formData.append("nonce", kvarc_ajax.nonce); 1325 formData.append( 1326 "username", 1327 this.querySelector('[name="username"]').value 1328 ); 1329 formData.append( 1330 "password", 1331 this.querySelector('[name="password"]').value 1332 ); 1333 formData.append( 1334 "remember", 1335 this.querySelector('[name="remember"]') 1336 ? this.querySelector('[name="remember"]').checked 1337 : false 1338 ); 1339 1340 fetch(kvarc_ajax.ajax_url, { 1341 method: "POST", 1342 body: formData, 1343 }) 1344 .then((response) => response.json()) 1345 .then((data) => { 1346 if (data.success) { 1347 showToast("УÑпеÑнÑй Ð²Ñ Ð¾Ð´!", "success"); 1348 setTimeout(() => { 1349 location.reload(); 1350 }, 1000); 1351 } else { 1352 showToast(data.data || "ÐÑибка Ð²Ñ Ð¾Ð´Ð°", "error"); 1353 } 1354 }) 1355 .catch((error) => { 1356 showToast("ÐÑибка ÑоединениÑ", "error"); 1357 }); 1358 }); 1359 } 1360 1361 if (registerForm) { 1362 registerForm.addEventListener("submit", function (e) { 1363 e.preventDefault(); 1364 1365 const password = this.querySelector('[name="password"]').value; 1366 const passwordConfirm = this.querySelector( 1367 '[name="password_confirm"]' 1368 ).value; 1369 1370 if (password !== passwordConfirm) { 1371 showToast("ÐаÑоли не ÑовпадаÑÑ", "error"); 1372 return; 1373 } 1374 1375 if (password.length < 6) { 1376 showToast("ÐаÑÐ¾Ð»Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ ÑодеÑжаÑÑ Ð¼Ð¸Ð½Ð¸Ð¼Ñм 6 Ñимволов", "error"); 1377 return; 1378 } 1379 1380 const formData = new FormData(); 1381 formData.append("action", "kvarc_register"); 1382 formData.append("nonce", kvarc_ajax.nonce); 1383 formData.append( 1384 "username", 1385 this.querySelector('[name="username"]').value 1386 ); 1387 formData.append("email", this.querySelector('[name="email"]').value); 1388 formData.append("password", password); 1389 1390 fetch(kvarc_ajax.ajax_url, { 1391 method: "POST", 1392 body: formData, 1393 }) 1394 .then((response) => response.json()) 1395 .then((data) => { 1396 if (data.success) { 1397 showToast("РегиÑÑÑаÑÐ¸Ñ ÑÑпеÑна!", "success"); 1398 setTimeout(() => { 1399 location.reload(); 1400 }, 1000); 1401 } else { 1402 showToast(data.data || "ÐÑибка ÑегиÑÑÑаÑии", "error"); 1403 } 1404 }) 1405 .catch((error) => { 1406 showToast("ÐÑибка ÑоединениÑ", "error"); 1407 }); 1408 }); 1409 } 1410 1411 if (logoutBtn) { 1412 logoutBtn.addEventListener("click", function (e) { 1413 e.preventDefault(); 1414 1415 const formData = new FormData(); 1416 formData.append("action", "kvarc_logout"); 1417 formData.append("nonce", kvarc_ajax.nonce); 1418 1419 fetch(kvarc_ajax.ajax_url, { 1420 method: "POST", 1421 body: formData, 1422 }) 1423 .then((response) => response.json()) 1424 .then((data) => { 1425 if (data.success) { 1426 showToast("ÐÑÑ Ð¾Ð´ вÑполнен!", "success"); 1427 setTimeout(() => { 1428 location.reload(); 1429 }, 1000); 1430 } 1431 }) 1432 .catch((error) => { 1433 showToast("ÐÑибка ÑоединениÑ", "error"); 1434 }); 1435 }); 1436 } 1437 1438 // ÐеÑеиниÑиализаÑÐ¸Ñ Ð¿Ñи AJAX загÑÑзке
1439 document.addEventListener('woocommerce_variations_loaded', function() { 1440 initVariationSwatches(); 1441 }); 1442 1443 // Ðогика Ð´Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ð°/ÑкÑÑÑÐ¸Ñ ÑпиÑка ваÑианÑов 1444 function initVariationDropdowns() { 1445 const variationHeaders = document.querySelectorAll('.variations th.label'); 1446 1447 variationHeaders.forEach(header => { 1448 header.addEventListener('click', function() { 1449 const row = this.closest('tr'); 1450 const variationList = row.querySelector('.single-product-variable-items'); 1451 1452 if (variationList) { 1453 // ÐакÑÑваем вÑе дÑÑгие ÑпиÑки 1454 document.querySelectorAll('.single-product-variable-items').forEach(list => { 1455 if (list !== variationList) { 1456 list.classList.remove('active'); 1457 } 1458 }); 1459 1460 // ÐеÑеклÑÑаем ÑекÑÑий ÑпиÑок 1461 variationList.classList.toggle('active'); 1462 } 1463 }); 1464 }); 1465 1466 // ÐакÑÑÑие пÑи клике вне ÑпиÑка 1467 document.addEventListener('click', function(e) { 1468 if (!e.target.closest('.variations')) { 1469 document.querySelectorAll('.single-product-variable-items').forEach(list => { 1470 list.classList.remove('active'); 1471 }); 1472 } 1473 }); 1474 } 1475 1476 // ÐапÑÑкаем иниÑиализаÑÐ¸Ñ dropdown'ов 1477 if (document.querySelector('.variations')) { 1478 initVariationDropdowns(); 1479 } 1480}); 1481 1482jQuery(document.body).on( 1483 "added_to_cart", 1484 function (event, fragments, cart_hash, button) { 1485 setTimeout(function () { 1486 jQuery(".added_to_cart").remove(); 1487 1488 var addedButtons = jQuery(".product-card__cart-btn.added"); 1489 addedButtons.each(function () { 1490 var $btn = jQuery(this); 1491 $btn.text("Ðобавлено").addClass("product-card__cart-btn--added"); 1492 1493 $btn.addClass("animate__animated animate__pulse"); 1494 setTimeout(function () { 1495 $btn.removeClass("animate__animated animate__pulse"); 1496 }, 1000); 1497 }); 1498 1499 showToast("Ð¢Ð¾Ð²Ð°Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½ в коÑзинÑ!", "success"); 1500 updateCartCount(); 1501 }, 100); 1502 } 1503); 1504 1505function updateCartCount() { 1506 var ajaxUrl = wc_add_to_cart_params.wc_ajax_url 1507 .toString() 1508 .replace("%%endpoint%%", "get_refreshed_fragments"); 1509 1510 jQuery.ajax({ 1511 url: ajaxUrl, 1512 type: "POST", 1513 success: function (data) { 1514 if (data && data.fragments) { 1515 jQuery.each(data.fragments, function (key, value) { 1516 var $element = jQuery(key); 1517 if ($element.length > 0) { 1518 $element.replaceWith(value); 1519 } 1520 }); 1521 } 1522 }, 1523 }); 1524} 1525 1526function updateWishlistCount() { 1527 if (typeof yith_wcwl_l10n !== "undefined") { 1528 jQuery.ajax({ 1529 url: yith_wcwl_l10n.ajax_url, 1530 type: "POST", 1531 data: { 1532 action: "yith_wcwl_update_wishlist_count", 1533 }, 1534 success: function (response) { 1535 if (response.count !== undefined) { 1536 var count = response.count; 1537 var $countElements = jQuery(".wishlist-count"); 1538 1539 if (count > 0) { 1540 if ($countElements.length > 0) { 1541 $countElements.text(count); 1542 } else { 1543 jQuery( 1544 '.icon-link:has(.icon-img[src*="favorite.svg"]), .mobile-menu__shortcut:has(img[src*="favorite.svg"])' 1545 ).each(function () { 1546 jQuery(this).append( 1547 '<span class="wishlist-count">' + count + "</span>" 1548 ); 1549 }); 1550 } 1551 } else { 1552 $countElements.remove(); 1553 } 1554 } 1555 }, 1556 }); 1557 } 1558} 1559 1560function showToast(message, type = "success") { 1561 var toast = jQuery( 1562 '<div class="toast toast--' + type + '">' + message + "</div>" 1563 ); 1564 jQuery("body").append(toast); 1565 1566 setTimeout(function () { 1567 toast.addClass("toast--show"); 1568 }, 100); 1569 1570 setTimeout(function () { 1571 toast.removeClass("toast--show"); 1572 setTimeout(function () { 1573 toast.remove(); 1574 }, 300); 1575 }, 3000); 1576} 1577 1578jQuery(document).ready(function ($) { 1579 // Ðбновление ÑÑеÑÑика избÑанного пÑи загÑÑзке ÑÑÑаниÑÑ 1580 updateWishlistCount(); 1581 1582 // ÐбÑабоÑÑики ÑобÑÑий YITH Wishlist 1583 $(document).on("yith_wcwl_reload_fragments", function () { 1584 updateWishlistCount(); 1585 }); 1586 1587 $(document).on("added_to_wishlist", function () { 1588 updateWishlistCount(); 1589 }); 1590 1591 $(document).on("removed_from_wishlist", function () { 1592 updateWishlistCount(); 1593 }); 1594 1595 // ÐÑинÑдиÑелÑÐ½Ð°Ñ Ð¸Ð½Ð¸ÑиализаÑÐ¸Ñ BeRocket ÑилÑÑÑов 1596 if (typeof berocket_aapf_widget_ready !== "undefined") { 1597 setTimeout(function () { 1598 berocket_aapf_widget_ready(); 1599 }, 100); 1600 } 1601 1602 if (typeof berocket_aapf_widget_ready_ajax !== "undefined") { 1603 setTimeout(function () { 1604 berocket_aapf_widget_ready_ajax(); 1605 }, 100); 1606 } 1607 1608 // ÐбÑабоÑка клика по кнопке ÑилÑÑÑаÑии 1609 $(".products-catalog__filter").on("click", function () { 1610 $(".mobile-filters-overlay").attr("aria-hidden", "false"); 1611 $("body").css("overflow", "hidden"); 1612 }); 1613 1614 // ÐакÑÑÑие мобилÑнÑÑ ÑилÑÑÑов 1615 $(".mobile-filters__back").on("click", function () { 1616 $(".mobile-filters-overlay").attr("aria-hidden", "true"); 1617 $("body").css("overflow", ""); 1618 }); 1619 1620 // ÐакÑÑÑие пÑи клике вне панели 1621 $(".mobile-filters-overlay").on("click", function (e) { 1622 if (e.target === this) { 1623 $(this).attr("aria-hidden", "true"); 1624 $("body").css("overflow", ""); 1625 } 1626 }); 1627 1628 // Ðнопка "ÐÑимениÑÑ" 1629 $(".mobile-filters__apply").on("click", function () { 1630 $(".mobile-filters-overlay").attr("aria-hidden", "true"); 1631 $("body").css("overflow", ""); 1632 // ÐдеÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ добавиÑÑ Ð»Ð¾Ð³Ð¸ÐºÑ Ð¿ÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÑилÑÑÑов 1633 }); 1634 1635 // СкÑÑваем ÑÑандаÑÑнÑй select ÑоÑÑиÑовки 1636 $(".woocommerce-ordering").hide(); 1637 1638 // ÐоказÑваем select пÑи клике на ÐºÐ½Ð¾Ð¿ÐºÑ Ð¡Ð¾ÑÑиÑовка 1639 $(".products-catalog__sort").on("click", function () { 1640 if (window.innerWidth <= 768) { 1641 // ÐобилÑÐ½Ð°Ñ Ð²ÐµÑÑÐ¸Ñ - показÑваем попап ÑÐ½Ð¸Ð·Ñ 1642 $(".products-catalog__sort-dropdown").addClass("active"); 1643 $("body").addClass("no-scroll"); 1644 } else { 1645 // ÐеÑкÑÐ¾Ð¿Ð½Ð°Ñ Ð²ÐµÑÑÐ¸Ñ - показÑваем дÑопдаÑн 1646 $(".woocommerce-ordering").toggle(); 1647 } 1648 }); 1649 1650 // ÐакÑÑÑие мобилÑного попапа ÑоÑÑиÑовки 1651 $(document).on("click", ".products-catalog__sort-dropdown", function (e) { 1652 if (e.target === this) { 1653 $(".products-catalog__sort-dropdown").removeClass("active"); 1654 $("body").removeClass("no-scroll"); 1655 } 1656 }); 1657 1658 // СкÑÑваем select пÑи клике вне его (деÑкÑоп) 1659 $(document).on("click", function (e) { 1660 if (window.innerWidth > 768) { 1661 if ( 1662 !$(e.target).closest(".products-catalog__sort, .woocommerce-ordering") 1663 .length 1664 ) { 1665 $(".woocommerce-ordering").hide(); 1666 } 1667 } 1668 }); 1669 1670 // BeRocket ÑилÑÑÑÑ Ð´ÑопдаÑÐ½Ñ (делегиÑование ÑобÑÑий) 1671 $(document).on("click", ".bapf_head", function () { 1672 var $filter = $(this).closest(".bapf_sfilter"); 1673 var $otherFilters = $(".bapf_sfilter").not($filter); 1674 1675 // ÐакÑÑваем дÑÑгие дÑопдаÑÐ½Ñ 1676 $otherFilters.removeClass("active"); 1677 1678 // ÐеÑеклÑÑаем ÑекÑÑий дÑопдаÑн 1679 $filter.toggleClass("active"); 1680 }); 1681 1682 // ÐакÑÑваем дÑопдаÑÐ½Ñ Ð¿Ñи клике вне Ð¸Ñ 1683 $(document).on("click", function (e) { 1684 if (!$(e.target).closest(".bapf_sfilter").length) { 1685 $(".bapf_sfilter").removeClass("active"); 1686 } 1687 }); 1688 1689 // ÐÐ»Ð°Ð²Ð½Ð°Ñ Ð¿ÑокÑÑÑка Ð´Ð»Ñ Ð½Ð°Ð²Ð¸Ð³Ð°Ñии 1690 const aboutNavLinks = document.querySelectorAll(".about-nav__link"); 1691 1692 aboutNavLinks.forEach((link) => { 1693 link.addEventListener("click", (e) => { 1694 e.preventDefault(); 1695 1696 const targetId = link.getAttribute("href").substring(1); 1697 const targetSection = document.getElementById(targetId); 1698
1699 if (targetSection) { 1700 targetSection.scrollIntoView({ 1701 behavior: "smooth", 1702 block: "start", 1703 }); 1704 1705 // ÐбновлÑем акÑивнÑÑ ÑÑÑÐ»ÐºÑ 1706 aboutNavLinks.forEach((l) => l.classList.remove("active")); 1707 link.classList.add("active"); 1708 } 1709 }); 1710 }); 1711 1712 // Ðбновление акÑивной ÑÑÑлки пÑи пÑокÑÑÑке 1713 const aboutSections = document.querySelectorAll(".about-section"); 1714 1715 function updateActiveNavLink() { 1716 const scrollPosition = window.scrollY + 100; 1717 1718 aboutSections.forEach((section) => { 1719 const sectionTop = section.offsetTop; 1720 const sectionHeight = section.offsetHeight; 1721 const sectionId = section.id; 1722 1723 if ( 1724 scrollPosition >= sectionTop && 1725 scrollPosition < sectionTop + sectionHeight 1726 ) { 1727 aboutNavLinks.forEach((link) => { 1728 link.classList.remove("active"); 1729 if (link.getAttribute("href") === "#" + sectionId) { 1730 link.classList.add("active"); 1731 } 1732 }); 1733 } 1734 }); 1735 } 1736 1737 window.addEventListener("scroll", updateActiveNavLink); 1738 1739 // Ð¡Ð»Ð°Ð¹Ð´ÐµÑ ÑеÑÑиÑикаÑов 1740 if (document.querySelector(".certificates-swiper")) { 1741 const certificatesSwiper = new Swiper(".certificates-swiper", { 1742 slidesPerView: 2.8, 1743 spaceBetween: 10, 1744 1745 1746 breakpoints: { 1747 768: { 1748 slidesPerView: 2, 1749 spaceBetween: 10, 1750 }, 1751 1024: { 1752 slidesPerView: 1, 1753 spaceBetween: 10, 1754 }, 1755 }, 1756 }); 1757 } 1758 1759 // ÐниÑиализаÑÐ¸Ñ Swiper Ð´Ð»Ñ Ð²Ð¸Ð´ÐµÐ¾ 1760 if (document.querySelector(".video-slider")) { 1761 const videoSwiper = new Swiper(".video-slider", { 1762 slidesPerView: 1.2, 1763 spaceBetween: 20, 1764 navigation: { 1765 nextEl: ".video-btn-next", 1766 prevEl: ".video-btn-prev", 1767 }, 1768 breakpoints: { 1769 768: { 1770 slidesPerView: 1, 1771 }, 1772 1024: { 1773 slidesPerView: 3, 1774 }, 1775 }, 1776 }); 1777 } 1778 1779 // ÐбÑабоÑка клика по видео 1780 const videoItems = document.querySelectorAll(".video-item"); 1781 1782 videoItems.forEach((item) => { 1783 item.addEventListener("click", () => { 1784 // ÐдеÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ добавиÑÑ Ð»Ð¾Ð³Ð¸ÐºÑ Ð´Ð»Ñ Ð¾ÑкÑÑÑÐ¸Ñ Ð²Ð¸Ð´ÐµÐ¾ 1785 }); 1786 }); 1787 1788 // ÐбÑабоÑка кнопки обÑаÑного звонка 1789 const callbackBtns = document.querySelectorAll(".callback-widget__btn"); 1790 1791 callbackBtns.forEach((btn) => { 1792 btn.addEventListener("click", () => { 1793 // ÐдеÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ добавиÑÑ Ð»Ð¾Ð³Ð¸ÐºÑ Ð´Ð»Ñ Ð¾ÑкÑÑÑÐ¸Ñ ÑоÑÐ¼Ñ Ð¾Ð±ÑаÑного звонка 1794 }); 1795 }); 1796 1797 // ÐбÑабоÑка кнопки "РазвеÑнÑÑÑ" в ÑекÑии "РнаÑ" 1798 const aboutExpandBtn = document.querySelector(".about__expand-btn"); 1799 const aboutText = document.querySelector(".about__text"); 1800 1801 if (aboutExpandBtn && aboutText) { 1802 // ÐолÑÑаем оÑигиналÑнÑй ÑекÑÑ ÐºÐ½Ð¾Ð¿ÐºÐ¸ из data аÑÑибÑÑа или из span 1803 const originalBtnText = aboutExpandBtn.querySelector("span").textContent; 1804 const expandedBtnText = "СвеÑнÑÑÑ"; 1805 1806 aboutExpandBtn.addEventListener("click", function () { 1807 const isExpanded = aboutText.classList.contains("about__text--expanded"); 1808 const btnText = this.querySelector("span"); 1809 const btnIcon = this.querySelector("svg"); 1810 1811 if (isExpanded) { 1812 // СвоÑаÑиваем 1813 aboutText.classList.remove("about__text--expanded"); 1814 btnText.textContent = originalBtnText; 1815 btnIcon.style.transform = "rotate(0deg)"; 1816 } else { 1817 // РазвоÑаÑиваем 1818 aboutText.classList.add("about__text--expanded"); 1819 btnText.textContent = expandedBtnText; 1820 btnIcon.style.transform = "rotate(180deg)"; 1821 } 1822 }); 1823 } 1824 1825 // ÐниÑиализаÑÐ¸Ñ Fancybox Ð´Ð»Ñ ÑеÑÑиÑикаÑов 1826 if (typeof $.fn.fancybox !== "undefined") { 1827 $('[data-fancybox="certificates"]').fancybox({ 1828 buttons: ["zoom", "slideShow", "fullScreen", "thumbs", "close"], 1829 animationEffect: "fade", 1830 transitionEffect: "slide", 1831 thumbs: { 1832 autoStart: true, 1833 }, 1834 touch: { 1835 vertical: true, 1836 momentum: true, 1837 }, 1838 beforeShow: function () { 1839 console.log("Fancybox beforeShow"); 1840 }, 1841 afterShow: function () { 1842 console.log("Fancybox afterShow"); 1843 }, 1844 beforeClose: function () { 1845 console.log("Fancybox beforeClose"); 1846 }, 1847 afterClose: function () { 1848 console.log("Fancybox afterClose"); 1849 // ÐоÑÑÑанавливаем каÑÑÑ Ð¿Ð¾Ñле закÑÑÑÐ¸Ñ 1850 if ( 1851 window.footerMap && 1852 typeof window.footerMap.container !== "undefined" 1853 ) { 1854 setTimeout(function () { 1855 window.footerMap.container.fitToViewport(); 1856 }, 100); 1857 } 1858 }, 1859 }); 1860 } 1861 1862 // ÐбÑабоÑка клика по ÑекбокÑÑ Ð² order-form 1863 $(".order-form .wpcf7-acceptance").on("click", function (e) { 1864 const checkbox = $(this).find('input[type="checkbox"]'); 1865 1866 if (checkbox.length) { 1867 const newState = !checkbox.prop("checked"); 1868 1869 checkbox.prop("checked", newState); 1870 1871 // ÐÑинÑдиÑелÑно обновлÑем ÑÑили 1872 const listItem = $(this).find(".wpcf7-list-item"); 1873 if (newState) { 1874 listItem.addClass("checked"); 1875 } else { 1876 listItem.removeClass("checked"); 1877 } 1878 1879 checkbox.trigger("change"); 1880 } 1881 }); 1882 1883 // ÐополниÑелÑÐ½Ð°Ñ Ð¾Ð±ÑабоÑка Ð´Ð»Ñ Ð¾Ñладки 1884 $(document).on( 1885 "change", 1886 '.order-form input[type="checkbox"]', 1887 function () {} 1888 ); 1889 1890 // ÐÑовеÑка загÑÑзки ÑлеменÑов 1891 $(document).ready(function () { 1892 // ÐвÑомаÑиÑеÑки оÑмеÑаем ÑÐµÐºÐ±Ð¾ÐºÑ 1893 $('.order-form input[type="checkbox"]').each(function () { 1894 $(this).prop("checked", true); 1895 $(this) 1896 .closest(".wpcf7-acceptance") 1897 .find(".wpcf7-list-item") 1898 .addClass("checked"); 1899 $(this).trigger("change"); 1900 }); 1901 1902 // ÐниÑиализаÑÐ¸Ñ Ð¼Ð°Ñки Ð´Ð»Ñ ÑелеÑона 1903 if (typeof $.fn.mask !== "undefined") { 1904 $('input[type="tel"], input[name="your-phone"]').mask( 1905 "+7 (000) 000-00-00", 1906 { 1907 placeholder: "+7 (___) ___-__-__", 1908 } 1909 ); 1910 } 1911 }); 1912 1913 // ÐниÑиализаÑÐ¸Ñ ÑлайдеÑа Ð´Ð»Ñ ÑÑÑаниÑÑ "ÐÑоизводÑÑво"
1914 if (document.querySelector(".production-slider")) { 1915 const productionSwiper = new Swiper(".production-slider", { 1916 slidesPerView: 1, 1917 spaceBetween: 0, 1918 loop: true, 1919 autoplay: { 1920 delay: 5000, 1921 disableOnInteraction: false, 1922 }, 1923 pagination: { 1924 el: ".swiper-pagination", 1925 clickable: true, 1926 }, 1927 navigation: { 1928 nextEl: ".swiper-button-next", 1929 prevEl: ".swiper-button-prev", 1930 }, 1931 effect: "fade", 1932 fadeEffect: { 1933 crossFade: true, 1934 }, 1935 speed: 800, 1936 }); 1937 } 1938 1939 // ÐалеÑÐµÑ 1940 if (document.querySelector(".gallery-slider")) { 1941 const gallerySwiper = new Swiper(".gallery-slider", { 1942 slidesPerView: 1, 1943 spaceBetween: 0, 1944 loop: true, 1945 autoplay: { 1946 delay: 4000, 1947 disableOnInteraction: false, 1948 }, 1949 navigation: { 1950 nextEl: ".gallery__btn--next", 1951 prevEl: ".gallery__btn--prev", 1952 }, 1953 pagination: { 1954 el: ".gallery__dots", 1955 clickable: true, 1956 }, 1957 effect: "fade", 1958 fadeEffect: { 1959 crossFade: true, 1960 }, 1961 speed: 600, 1962 }); 1963 } 1964 1965 // ÐÑпиÑÑ Ð² один клик 1966 document.addEventListener("click", function (e) { 1967 if ( 1968 e.target.classList.contains("product-card__buy-btn") || 1969 e.target.classList.contains("product-single__buy-btn") 1970 ) { 1971 e.preventDefault(); 1972 1973 const productId = e.target.dataset.productId; 1974 let productName = ""; 1975 1976 // ÐÐ»Ñ ÐºÐ°ÑÑоÑки ÑоваÑа 1977 if (e.target.classList.contains("product-card__buy-btn")) { 1978 productName = 1979 e.target 1980 .closest(".product-card") 1981 .querySelector(".product-card__title")?.textContent || ""; 1982 } 1983 // ÐÐ»Ñ ÑÑÑаниÑÑ ÑоваÑа 1984 else if (e.target.classList.contains("product-single__buy-btn")) { 1985 productName = 1986 document.querySelector(".product-info__title")?.textContent || 1987 document.querySelector(".entry-title")?.textContent || 1988 document.querySelector("h1")?.textContent || 1989 ""; 1990 } 1991 1992 // ÐÑкÑÑваем попап Ñ ÑоÑмой 1993 if (typeof openPopup === "function") { 1994 openPopup("buy-one-click"); 1995 1996 // ÐеÑедаем даннÑе о ÑоваÑе в ÑоÑÐ¼Ñ 1997 setTimeout(() => { 1998 const form = document.querySelector( 1999 ".popup-buy-one-click .wpcf7-form" 2000 ); 2001 if (form) { 2002 const productIdField = form.querySelector( 2003 'input[name="product-id"]' 2004 ); 2005 const productNameField = form.querySelector( 2006 'input[name="product-name"]' 2007 ); 2008 2009 if (productIdField) { 2010 productIdField.value = productId; 2011 } 2012 if (productNameField) { 2013 productNameField.value = productName; 2014 } 2015 } else { 2016 } 2017 }, 100); 2018 } 2019 } 2020 }); 2021 2022 // FAQ ÑÑнкÑионалÑноÑÑÑ Ð´Ð»Ñ Ð³Ð»Ð°Ð²Ð½Ð¾Ð¹ ÑÑÑаниÑÑ 2023 function initFAQ() { 2024 const faqTabs = document.querySelectorAll(".faq__tab"); 2025 const faqQuestions = document.querySelectorAll(".faq__question"); 2026 2027 // ÐÑовеÑÑем, не иниÑиализиÑÐ¾Ð²Ð°Ð½Ñ Ð»Ð¸ Ñже ÑлеменÑÑ 2028 if (faqTabs.length > 0 && faqTabs[0].hasAttribute("data-initialized")) { 2029 console.log("FAQ already initialized, skipping..."); 2030 return; 2031 } 2032 2033 // ÐниÑиализаÑиÑ: ÑкÑÑваем вÑе вопÑоÑÑ, кÑоме акÑивного Ñаба 2034 const activeTab = document.querySelector(".faq__tab--active"); 2035 if (activeTab) { 2036 const activeTabName = activeTab.dataset.tab; 2037 faqQuestions.forEach((question) => { 2038 const questionTab = question.dataset.tab; 2039 if (questionTab === activeTabName) { 2040 question.style.display = "block"; 2041 } else { 2042 question.style.display = "none"; 2043 } 2044 }); 2045 } 2046 2047 // ÐеÑеклÑÑение FAQ Ñабов 2048 if (faqTabs.length > 0) { 2049 faqTabs.forEach((btn) => { 2050 btn.addEventListener("click", (e) => { 2051 e.preventDefault(); 2052 e.stopPropagation(); 2053 2054 const tab = btn.dataset.tab; 2055 2056 // УбиÑаем акÑивнÑй клаÑÑ Ñо вÑÐµÑ ÐºÐ½Ð¾Ð¿Ð¾Ðº
2057 faqTabs.forEach((b) => b.classList.remove("faq__tab--active")); 2058 // ÐобавлÑем акÑивнÑй клаÑÑ Ðº нажаÑой кнопке 2059 btn.classList.add("faq__tab--active"); 2060 2061 // ÐоказÑваем/ÑкÑÑваем вопÑоÑÑ Ð² завиÑимоÑÑи Ð¾Ñ Ñаба 2062 faqQuestions.forEach((question) => { 2063 const questionTab = question.dataset.tab; 2064 if (questionTab === tab) { 2065 question.style.display = "block"; 2066 } else { 2067 question.style.display = "none"; 2068 // ÐакÑÑваем вопÑоÑÑ Ð½ÐµÐ°ÐºÑивнÑÑ Ñабов 2069 question.classList.remove("faq__question--active"); 2070 } 2071 }); 2072 2073 // ÐоказÑваем пеÑвÑй акÑивнÑй вопÑÐ¾Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ Ñаба 2074 const firstActiveQuestionOfTab = document.querySelector( 2075 `.faq__question[data-tab="${tab}"].faq__question--active` 2076 ); 2077 if (firstActiveQuestionOfTab) { 2078 // ÐÑÑавлÑем пеÑвÑй акÑивнÑй вопÑÐ¾Ñ Ð¾ÑкÑÑÑÑм 2079 } else { 2080 // ÐÑли Ð½ÐµÑ Ð°ÐºÑивнÑÑ Ð²Ð¾Ð¿ÑоÑов, оÑкÑÑваем пеÑвÑй 2081 const firstQuestionOfTab = document.querySelector( 2082 `.faq__question[data-tab="${tab}"]` 2083 ); 2084 if (firstQuestionOfTab) { 2085 firstQuestionOfTab.classList.add("faq__question--active"); 2086 } 2087 } 2088 }); 2089 }); 2090 } 2091 2092 // FAQ аккоÑдеон 2093 if (faqQuestions.length > 0) { 2094 faqQuestions.forEach((item) => { 2095 const btn = item.querySelector(".faq__question-btn"); 2096 2097 if (!btn) return; 2098 2099 const toggleItem = (e) => { 2100 e.preventDefault(); 2101 e.stopPropagation(); 2102 2103 const isActive = item.classList.contains("faq__question--active"); 2104 2105 // ÐакÑÑваем вÑе оÑÑалÑнÑе ÑлеменÑÑ Ð² Ñом же Ñабе 2106 const currentTab = item.dataset.tab; 2107 const questionsInSameTab = document.querySelectorAll( 2108 `.faq__question[data-tab="${currentTab}"]` 2109 ); 2110 questionsInSameTab.forEach((otherItem) => { 2111 if (otherItem !== item) { 2112 otherItem.classList.remove("faq__question--active"); 2113 } 2114 }); 2115 2116 // ÐеÑеклÑÑаем ÑекÑÑий ÑÐ»ÐµÐ¼ÐµÐ½Ñ 2117 if (isActive) { 2118 item.classList.remove("faq__question--active"); 2119 } else { 2120 item.classList.add("faq__question--active"); 2121 } 2122 }; 2123 2124 btn.addEventListener("click", toggleItem); 2125 }); 2126 } 2127 } 2128 2129 // FAQ ÑÑнкÑионалÑноÑÑÑ Ð´Ð»Ñ ÑÑÑаниÑÑ FAQ 2130 function initFAQPage() { 2131 const faqNavBtns = document.querySelectorAll(".faq-nav__btn"); 2132 const faqCategories = document.querySelectorAll(".faq-category"); 2133 const faqItems = document.querySelectorAll(".faq-item"); 2134 2135 console.log("FAQ Page Init - Found elements:", { 2136 navBtns: faqNavBtns.length, 2137 categories: faqCategories.length, 2138 items: faqItems.length, 2139 }); 2140 2141 // ÐеÑеклÑÑение FAQ каÑегоÑий (Ñабов) 2142 if (faqNavBtns.length > 0) { 2143 faqNavBtns.forEach((btn) => { 2144 btn.addEventListener("click", function () { 2145 const category = this.getAttribute("data-category"); 2146 console.log("FAQ Tab clicked:", category); 2147 2148 // УбиÑаем акÑивнÑй клаÑÑ Ñ Ð²ÑÐµÑ ÐºÐ½Ð¾Ð¿Ð¾Ðº 2149 faqNavBtns.forEach((b) => b.classList.remove("faq-nav__btn--active")); 2150 2151 // ÐобавлÑем акÑивнÑй клаÑÑ Ðº ÑекÑÑей кнопке 2152 btn.classList.add("faq-nav__btn--active"); 2153 2154 // СкÑÑваем вÑе каÑегоÑии 2155 faqCategories.forEach((category) => { 2156 category.classList.remove("faq-category--active"); 2157 }); 2158 2159 // ÐоказÑваем вÑбÑаннÑÑ ÐºÐ°ÑегоÑÐ¸Ñ 2160 const activeCategory = document.querySelector( 2161 `.faq-category[data-category="${category}"]` 2162 ); 2163 2164 if (activeCategory) { 2165 activeCategory.classList.add("faq-category--active"); 2166 } 2167 }); 2168 }); 2169 } 2170 2171 // FAQ аккоÑдеон 2172 if (faqItems.length > 0) {
2173 faqItems.forEach((item, index) => { 2174 const toggleBtn = item.querySelector(".faq-item__toggle"); 2175 const header = item.querySelector(".faq-item__header"); 2176 2177 console.log(`FAQ Item ${index}:`, { 2178 hasToggleBtn: !!toggleBtn, 2179 hasHeader: !!header, 2180 }); 2181 2182 // ÐобавлÑем обÑабоÑÑик на ÐºÐ½Ð¾Ð¿ÐºÑ 2183 if (toggleBtn) { 2184 toggleBtn.addEventListener("click", function (e) { 2185 e.preventDefault(); 2186 e.stopPropagation(); 2187 console.log("FAQ Toggle clicked for item:", index); 2188 2189 const isActive = item.classList.contains("faq-item--active"); 2190 2191 // ÐакÑÑваем вÑе дÑÑгие вопÑоÑÑ 2192 faqItems.forEach((otherItem) => { 2193 if (otherItem !== item) { 2194 otherItem.classList.remove("faq-item--active"); 2195 } 2196 }); 2197 2198 // ÐеÑеклÑÑаем ÑекÑÑий вопÑÐ¾Ñ 2199 if (isActive) { 2200 item.classList.remove("faq-item--active"); 2201 } else { 2202 item.classList.add("faq-item--active"); 2203 } 2204 }); 2205 } 2206 2207 // ÐобавлÑем обÑабоÑÑик на заголовок 2208 if (header) { 2209 header.addEventListener("click", function (e) { 2210 e.preventDefault(); 2211 e.stopPropagation(); 2212 console.log("FAQ Header clicked for item:", index); 2213 2214 const isActive = item.classList.contains("faq-item--active"); 2215 2216 // ÐакÑÑваем вÑе дÑÑгие вопÑоÑÑ 2217 faqItems.forEach((otherItem) => { 2218 if (otherItem !== item) { 2219 otherItem.classList.remove("faq-item--active"); 2220 } 2221 }); 2222 2223 // ÐеÑеклÑÑаем ÑекÑÑий вопÑÐ¾Ñ 2224 if (isActive) { 2225 item.classList.remove("faq-item--active"); 2226 } else { 2227 item.classList.add("faq-item--active"); 2228 } 2229 }); 2230 } 2231 }); 2232 } 2233 } 2234 2235 // ÐобилÑÐ½Ð°Ñ Ð½Ð°Ð²Ð¸Ð³Ð°ÑÐ¸Ñ Ð´Ð»Ñ ÑÑÑÐ°Ð½Ð¸Ñ 2236 const mobileNavToggle = document.getElementById("mobileNavToggle"); 2237 const mobileNavOverlay = document.getElementById("mobileNavOverlay"); 2238 const mobileNavClose = document.getElementById("mobileNavClose"); 2239 const mobileNavLinks = document.querySelectorAll(".mobile-nav__link"); 2240 2241 if (mobileNavToggle && mobileNavOverlay) { 2242 // ÐÑкÑÑÑие мобилÑной навигаÑии 2243 mobileNavToggle.addEventListener("click", () => { 2244 mobileNavToggle.classList.add("active"); 2245 mobileNavOverlay.style.display = "block"; 2246 setTimeout(() => { 2247 mobileNavOverlay.classList.add("active"); 2248 }, 10); 2249 document.body.style.overflow = "hidden"; 2250 }); 2251 2252 // ÐакÑÑÑие мобилÑной навигаÑии 2253 const closeMobileNav = () => { 2254 mobileNavToggle.classList.remove("active"); 2255 mobileNavOverlay.classList.remove("active"); 2256 setTimeout(() => { 2257 mobileNavOverlay.style.display = "none"; 2258 }, 300); 2259 document.body.style.overflow = ""; 2260 }; 2261 2262 if (mobileNavClose) { 2263 mobileNavClose.addEventListener("click", closeMobileNav); 2264 } 2265 2266 // ÐакÑÑÑие пÑи клике на овеÑлей 2267 mobileNavOverlay.addEventListener("click", (e) => { 2268 if (e.target === mobileNavOverlay) { 2269 closeMobileNav(); 2270 } 2271 }); 2272 2273 // ÐакÑÑÑие пÑи клике на ÑÑÑÐ»ÐºÑ 2274 mobileNavLinks.forEach((link) => { 2275 link.addEventListener("click", () => { 2276 closeMobileNav(); 2277 }); 2278 }); 2279 2280 // ÐакÑÑÑие пÑи нажаÑии Escape 2281 document.addEventListener("keydown", (e) => { 2282 if (e.key === "Escape" && mobileNavOverlay.classList.contains("active")) { 2283 closeMobileNav(); 2284 } 2285 }); 2286 } 2287 2288 // About Certificates Swiper 2289 if (document.querySelector(".about-certificates-swiper")) { 2290 const aboutCertificatesSwiper = new Swiper(".about-certificates-swiper", { 2291 slidesPerView: 1.2, 2292 spaceBetween: 5, 2293 effect: "coverflow", 2294 grabCursor: true, 2295 centeredSlides: true, 2296 coverflowEffect: { 2297 rotate: 0, 2298 stretch: 0, 2299 depth: 100, 2300 modifier: 2, 2301 slideShadows: true, 2302 }, 2303 navigation: { 2304 nextEl: ".certificates-btn-next", 2305 prevEl: ".certificates-btn-prev", 2306 }, 2307 breakpoints: { 2308 480: { 2309 slidesPerView: 1.2, 2310 spaceBetween: 5, 2311 effect: "coverflow", 2312 centeredSlides: true, 2313 }, 2314 768: { 2315 slidesPerView: 2, 2316 spaceBetween: 30, 2317 effect: "slide", 2318 centeredSlides: false, 2319 }, 2320 1920: { 2321 slidesPerView: 3, 2322 spaceBetween: 40, 2323 effect: "slide", 2324 centeredSlides: false, 2325 }, 2326 }, 2327 }); 2328 } 2329 2330 // ÐапÑÑкаем иниÑиализаÑÐ¸Ñ FAQ 2331 let faqInitialized = false;
2332 let faqPageInitialized = false; 2333 2334 function initializeFAQOnce() { 2335 if (!faqInitialized) { 2336 initFAQ(); 2337 faqInitialized = true; 2338 } 2339 } 2340 2341 function initializeFAQPageOnce() { 2342 if (!faqPageInitialized) { 2343 initFAQPage(); 2344 faqPageInitialized = true; 2345 } 2346 } 2347 2348 // ÐниÑиализиÑÑем FAQ Ð´Ð»Ñ Ð³Ð»Ð°Ð²Ð½Ð¾Ð¹ ÑÑÑаниÑÑ 2349 initializeFAQOnce(); 2350 2351 // ÐниÑиализиÑÑем FAQ Ð´Ð»Ñ ÑÑÑаниÑÑ FAQ 2352 initializeFAQPageOnce(); 2353 2354 // ÐополниÑелÑÐ½Ð°Ñ Ð¸Ð½Ð¸ÑиализаÑÐ¸Ñ Ð¿Ñи загÑÑзке DOM 2355 document.addEventListener("DOMContentLoaded", function () { 2356 console.log("DOM Content Loaded - Re-initializing FAQ Page"); 2357 initializeFAQPageOnce(); 2358 }); 2359 2360 // ÐлобалÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð´Ð»Ñ Ð¿ÐµÑеклÑÑÐµÐ½Ð¸Ñ FAQ ÑлеменÑов 2361 window.toggleFAQItem = function (header) { 2362 const item = header.closest(".faq-item"); 2363 if (!item) return; 2364 2365 console.log("Global toggleFAQItem called for:", item); 2366 2367 const isActive = item.classList.contains("faq-item--active"); 2368 2369 // ÐакÑÑваем вÑе дÑÑгие вопÑоÑÑ 2370 const allItems = document.querySelectorAll(".faq-item"); 2371 allItems.forEach((otherItem) => { 2372 if (otherItem !== item) { 2373 otherItem.classList.remove("faq-item--active"); 2374 } 2375 }); 2376 2377 // ÐеÑеклÑÑаем ÑекÑÑий вопÑÐ¾Ñ 2378 if (isActive) { 2379 item.classList.remove("faq-item--active"); 2380 } else { 2381 item.classList.add("faq-item--active"); 2382 } 2383 }; 2384 2385 // РейÑинг звездами 2386 $(document).on("click", ".stars a", function (e) { 2387 e.preventDefault(); 2388 var rating = $(this).attr("class").replace("star-", ""); 2389 2390 // ÐбновлÑем акÑивнÑе Ð·Ð²ÐµÐ·Ð´Ñ 2391 $(".stars a").removeClass("active"); 2392 $(".stars a").each(function (index) { 2393 if (index < rating) { 2394 $(this).addClass("active"); 2395 } 2396 }); 2397 2398 // УÑÑанавливаем знаÑение в ÑкÑÑÑÑй select 2399 $("#rating").val(rating); 2400 }); 2401 2402 // Hover ÑÑÑÐµÐºÑ Ð´Ð»Ñ Ð·Ð²ÐµÐ·Ð´ 2403 $(document).on("mouseenter", ".stars a", function () { 2404 var rating = $(this).attr("class").replace("star-", ""); 2405 $(".stars a").removeClass("hover"); 2406 $(".stars a").each(function (index) { 2407 if (index < rating) { 2408 $(this).addClass("hover"); 2409 } 2410 }); 2411 }); 2412 2413 $(document).on("mouseleave", ".stars", function () { 2414 $(".stars a").removeClass("hover"); 2415 }); 2416 2417 // РаÑкÑÑваÑÑиеÑÑ Ð±Ð»Ð¾ÐºÐ¸ в ÑÑÑеÑе Ð´Ð»Ñ Ð¼Ð¾Ð±Ð¸Ð»Ñной веÑÑии 2418 const footerColumnToggles = document.querySelectorAll(
2419 ".footer__column-toggle" 2420 ); 2421 2422 footerColumnToggles.forEach((toggle) => { 2423 toggle.addEventListener("click", function () { 2424 const column = this.closest(".footer__column"); 2425 const isActive = column.classList.contains("active"); 2426 2427 // ÐакÑÑваем вÑе дÑÑгие колонки 2428 document.querySelectorAll(".footer__column").forEach((col) => { 2429 col.classList.remove("active"); 2430 }); 2431 2432 // ÐÑкÑÑваем ÑекÑÑÑÑ ÐºÐ¾Ð»Ð¾Ð½ÐºÑ ÐµÑли она бÑла закÑÑÑа 2433 if (!isActive) { 2434 column.classList.add("active"); 2435 } 2436 }); 2437 }); 2438 2439 // ÐвеÑлей Ð´Ð»Ñ Ð²Ð°ÑиаÑий ÑоваÑа 2440 let overlayObserver = null; 2441 let overlayInitialized = false; 2442 2443 function initVariationOverlay() { 2444 if (overlayInitialized) { 2445 console.log('ÐвеÑлей Ñже иниÑиализиÑован, пÑопÑÑкаем...'); 2446 return; 2447 } 2448 2449 console.log('ÐниÑиализаÑÐ¸Ñ Ð¾Ð²ÐµÑÐ»ÐµÑ Ð²Ð°ÑиаÑий...'); 2450 2451 // УдалÑем пÑедÑдÑÑий observer еÑли еÑÑÑ 2452 if (overlayObserver) { 2453 overlayObserver.disconnect(); 2454 } 2455 2456 // ÐаблÑдаем за изменениÑми клаÑÑа active 2457 overlayObserver = new MutationObserver(function(mutations) { 2458 mutations.forEach(function(mutation) { 2459 if (mutation.type === 'attributes' && mutation.attributeName === 'class') { 2460 const target = mutation.target; 2461 if (target.classList.contains('active') && target.classList.contains('variable-items-wrapper')) { 2462 console.log('Ðайден акÑивнÑй wrapper:', target); 2463 const tr = target.closest('tr'); 2464 if (tr) { 2465 const label = tr.querySelector('.label label'); 2466 if (label) { 2467 const attributeLabel = label.textContent; 2468 showVariationOverlay(attributeLabel, target); 2469 } 2470 } 2471 } 2472 } 2473 }); 2474 }); 2475 2476 // ÐаблÑдаем за вÑеми wrapper'ами 2477 const wrappers = document.querySelectorAll('.variable-items-wrapper'); 2478 console.log('Ðайдено wrapper\'ов:', wrappers.length); 2479 2480 wrappers.forEach((wrapper, index) => { 2481 console.log(`ÐаблÑдение за wrapper ${index + 1}:`, wrapper); 2482 overlayObserver.observe(wrapper, { attributes: true, attributeFilter: ['class'] }); 2483 2484 // ÐÑовеÑÑем, еÑÑÑ Ð»Ð¸ Ñже клаÑÑ active 2485 if (wrapper.classList.contains('active')) { 2486 console.log('Wrapper Ñже акÑивен:', wrapper); 2487 const tr = wrapper.closest('tr'); 2488 if (tr) { 2489 const label = tr.querySelector('.label label'); 2490 if (label) { 2491 const attributeLabel = label.textContent; 2492 showVariationOverlay(attributeLabel, wrapper); 2493 } 2494 } 2495 } 2496 }); 2497 2498 overlayInitialized = true; 2499 console.log('ÐвеÑлей иниÑиализиÑован ÑÑпеÑно'); 2500 } 2501 2502 function showVariationOverlay(attributeLabel, wrapper) { 2503 // ÐÑовеÑÑем, Ð½ÐµÑ Ð»Ð¸ Ñже оÑкÑÑÑого овеÑÐ»ÐµÑ 2504 if (document.querySelector('.variation-overlay')) { 2505 console.log('ÐвеÑлей Ñже оÑкÑÑÑ, пÑопÑÑкаем'); 2506 return; 2507 } 2508 2509 // ÐÑовеÑÑем, не закÑÑвалÑÑ Ð»Ð¸ овеÑлей недавно (заÑиÑа Ð¾Ñ Ð´Ð²Ð¾Ð¹Ð½Ð¾Ð³Ð¾ клика) 2510 if (wrapper.dataset.overlayJustClosed) { 2511 console.log('ÐвеÑлей ÑолÑко ÑÑо закÑÑлÑÑ, пÑопÑÑкаем'); 2512 return; 2513 } 2514 2515 console.log('Создание овеÑÐ»ÐµÑ Ð´Ð»Ñ:', attributeLabel); 2516 const overlay = document.createElement('div'); 2517 overlay.className = 'variation-overlay'; 2518 overlay.innerHTML = ` 2519 <div class="variation-overlay-content"> 2520 <button class="variation-overlay-close">×</button> 2521 <h3 class="variation-overlay-title">ÐÑбеÑиÑе ${attributeLabel}</h3> 2522 <div class="variation-overlay-variations"></div> 2523 </div> 2524 `; 2525 2526 const variationsContainer = overlay.querySelector('.variation-overlay-variations'); 2527 const clonedWrapper = wrapper.cloneNode(true); 2528 console.log('ÐлониÑованнÑй wrapper:', clonedWrapper); 2529 variationsContainer.appendChild(clonedWrapper); 2530 2531 document.body.appendChild(overlay); 2532 console.log('ÐвеÑлей добавлен в DOM'); 2533 2534 setTimeout(() => { 2535 overlay.classList.add('active'); 2536 console.log('ÐвеÑлей акÑивиÑован'); 2537 }, 10); 2538 2539 const closeBtn = overlay.querySelector('.variation-overlay-close'); 2540 2541 function closeOverlay() { 2542 overlay.classList.remove('active'); 2543 2544 // УÑÑанавливаем Ñлаг о закÑÑÑии овеÑÐ»ÐµÑ 2545 wrapper.dataset.overlayJustClosed = 'true'; 2546 setTimeout(() => { 2547 delete wrapper.dataset.overlayJustClosed; 2548 }, 500); 2549 2550 setTimeout(() => { 2551 if (document.body.contains(overlay)) { 2552 document.body.removeChild(overlay); 2553 } 2554 }, 300); 2555 } 2556 2557 closeBtn.addEventListener('click', closeOverlay); 2558 2559 overlay.addEventListener('click', function(e) { 2560 if (e.target === overlay) { 2561 closeOverlay(); 2562 } 2563 }); 2564 2565 document.addEventListener('keydown', function closeOnEscape(e) { 2566 if (e.key === 'Escape') { 2567 closeOverlay(); 2568 document.removeEventListener('keydown', closeOnEscape); 2569 } 2570 }); 2571 2572 // ÐÑполÑзÑем делегиÑование ÑобÑÑий Ð´Ð»Ñ Ð±Ð¾Ð»ÐµÐµ надежной ÑабоÑÑ 2573 clonedWrapper.addEventListener('click', function(e) { 2574 const item = e.target.closest('.variable-item'); 2575 if (!item) { 2576 console.log('Ðлик не по ÑлеменÑÑ Ð²Ð°ÑиаÑии'); 2577 return; 2578 } 2579 2580 e.preventDefault(); 2581 e.stopPropagation(); 2582 console.log('Ðлик по клониÑÐ¾Ð²Ð°Ð½Ð½Ð¾Ð¼Ñ ÑлеменÑÑ:', item); 2583 2584 const value = item.getAttribute('data-value'); 2585 console.log('ÐнаÑение ÑлеменÑа:', value); 2586 2587 if (value) { 2588 // ÐÑем оÑигиналÑнÑй ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¿Ð¾ data-value 2589 const originalItem = wrapper.querySelector(`[data-value="${value}"]`); 2590 console.log('Ðайден оÑигиналÑнÑй ÑлеменÑ:', originalItem); 2591 2592 if (originalItem) { 2593 console.log('ТÑиггеÑим клик по оÑигиналÑÐ½Ð¾Ð¼Ñ ÑлеменÑÑ'); 2594 2595 // ÐÑоÑÑо ÑÑиггеÑим клик по оÑигиналÑÐ½Ð¾Ð¼Ñ ÑлеменÑÑ 2596 // ÐÑо Ð¿Ð¾Ð·Ð²Ð¾Ð»Ð¸Ñ Ð¾ÑигиналÑÐ½Ð¾Ð¼Ñ ÑкÑипÑÑ WooCommerce обÑабоÑаÑÑ Ð²ÑÐ±Ð¾Ñ 2597 originalItem.click(); 2598 2599 console.log('ÐакÑÑÑие овеÑлеÑ'); 2600 closeOverlay(); 2601 } else { 2602 console.log('ÐÑигиналÑнÑй ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð½Ðµ найден!'); 2603 } 2604 } else { 2605 console.log('ÐнаÑение data-value не найдено!'); 2606 } 2607 }); 2608 2609 // ÐобавлÑем ÑÑили Ð´Ð»Ñ ÐºÐ»Ð¸ÐºÐ°Ð±ÐµÐ»ÑноÑÑи вÑем ÑлеменÑам 2610 const clonedItems = clonedWrapper.querySelectorAll('.variable-item'); 2611 console.log('ÐлониÑованнÑе ÑлеменÑÑ:', clonedItems.length); 2612
2613 clonedItems.forEach((item, index) => { 2614 console.log(`ÐбÑабоÑка клониÑованного ÑлеменÑа ${index + 1}:`, item); 2615 item.style.cursor = 'pointer'; 2616 item.style.pointerEvents = 'auto'; 2617 }); 2618 } 2619 2620 // ÐниÑиализаÑÐ¸Ñ Ð¿Ð¾Ñле загÑÑзки DOM 2621 document.addEventListener('DOMContentLoaded', function() { 2622 console.log('DOM загÑÑжен, иниÑиализаÑÐ¸Ñ Ð¾Ð²ÐµÑлеÑ...'); 2623 initVariationOverlay(); 2624 }); 2625 2626 // ÐовÑоÑÐ½Ð°Ñ Ð¸Ð½Ð¸ÑиализаÑÐ¸Ñ Ð´Ð»Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸ÑеÑки загÑÑженного конÑенÑа 2627 setTimeout(() => { 2628 console.log('ÐовÑоÑÐ½Ð°Ñ Ð¸Ð½Ð¸ÑиализаÑÐ¸Ñ Ð¾Ð²ÐµÑÐ»ÐµÑ ÑеÑез 1 ÑекÑндÑ...'); 2629 initVariationOverlay(); 2630 }, 1000); 2631 2632 // ÐополниÑелÑÐ½Ð°Ñ Ð¸Ð½Ð¸ÑиализаÑÐ¸Ñ ÑеÑез 3 ÑекÑÐ½Ð´Ñ 2633 setTimeout(() => { 2634 console.log('ÐополниÑелÑÐ½Ð°Ñ Ð¸Ð½Ð¸ÑиализаÑÐ¸Ñ Ð¾Ð²ÐµÑÐ»ÐµÑ ÑеÑез 3 ÑекÑндÑ...'); 2635 initVariationOverlay(); 2636 }, 3000); 2637}); 2638 2639 2640document.querySelector('.open_cities_popup').addEventListener('click', function(e) { 2641 e.preventDefault(); 2642 document.querySelector('a.geolocation__link').click(); 2643}); 2644 2645 2646jQuery(document).ready(function() { 2647 2648 function scrollToCity(targetId) { 2649 var target = jQuery('#id-' + targetId); 2650 2651 if (!target.length) return; 2652 2653 var windowWidth = jQuery(window).width(); 2654 var headerHeight = windowWidth <= 767 ? 60 : 120; 2655 var offset = 20; 2656 2657 jQuery('html, body').animate({ 2658 scrollTop: target.offset().top - headerHeight - offset 2659 }, 800); 2660 } 2661 2662 // Ðлик по ÑÑÑлке на ÑÑÑаниÑе конÑакÑов 2663 jQuery('.city-anchor a').on('click', function(e) { 2664 var cityId = jQuery(this).data('city'); 2665 2666 if (cityId) { 2667 e.preventDefault(); 2668 scrollToCity(cityId); 2669 } 2670 }); 2671 2672 // ÐбÑабоÑка GET-паÑамеÑÑа city (пеÑÐµÑ Ð¾Ð´ Ñ FAQ) 2673 var urlParams = new URLSearchParams(window.location.search); 2674 var cityId = urlParams.get('city'); 2675 2676 if (cityId) { 2677 setTimeout(function() { 2678 scrollToCity(cityId); 2679 }, 300); 2680 } 2681}); 2682 2683// авÑозаполнение гоÑода в ÑоÑÐ¼Ð°Ñ 2684document.addEventListener('DOMContentLoaded', function() { 2685 const buttons = document.querySelectorAll('.btn'); 2686 2687 buttons.forEach(function(btn) { 2688 btn.addEventListener('click', function() { 2689 const citySpan = document.querySelector('.geolocation__value'); 2690 if (!citySpan) return; 2691 2692 const city = citySpan.textContent.trim(); 2693 if (city === 'ÐпÑеделение...' || city === '') return; 2694 2695 document.querySelectorAll('.your-city-auto').forEach(function(input) { 2696 input.value = city; 2697 }); 2698 }); 2699 }); 2700}); 2701 2702document.addEventListener('DOMContentLoaded', function() { 2703 document.querySelectorAll('.popup__form').forEach(function(form) { 2704 const submitBtns = form.querySelectorAll('.popup__submit'); 2705 if (submitBtns.length < 2) return; 2706 2707 const first = submitBtns[0]; 2708 const second = submitBtns[1]; 2709 2710 // Ðлик по вÑоÑой â имиÑаÑÐ¸Ñ ÐºÐ»Ð¸ÐºÐ° по пеÑвой 2711 second.addEventListener('click', function(e) { 2712 e.preventDefault(); 2713 first.click(); 2714 }); 2715 2716 // Ð¡Ð¸Ð½Ñ ÑонизаÑÐ¸Ñ ÑоÑÑоÑÐ½Ð¸Ñ 2717 new MutationObserver(function() { 2718 second.disabled = first.disabled; 2719 second.classList.toggle('popup__submit--disabled', first.classList.contains('popup__submit--disabled')); 2720 }).observe(first, { attributes: true, attributeFilter: ['disabled', 'class'] }); 2721 2722 second.disabled = first.disabled; 2723 second.classList.toggle('popup__submit--disabled', first.classList.contains('popup__submit--disabled')); 2724 }); 2725});
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.