1/* vh fix */ 2BX.ready(function () { 3 4 window.addEventListener('DOMContentLoaded', utility.setVH()); 5 window.addEventListener('resize', utility.debounce(utility.setVH, 250)); 6 7 8 /* load assets */ 9 if (!disableAnimations) { 10 var imgLoad = imagesLoaded(document.querySelector('.scroll-container'), { 11 background: '.hero__back' 12 }); 13 var heroAnimations = HeroAnimations; 14 imgLoad.on('done', function () { 15 /* hero Animations start */ 16 heroAnimations.initHero(); 17 }); 18 imgLoad.on('fail', function () { 19 console.log('FAIL - all images loaded, at least one is broken'); 20 /* hero Animations start */ 21 heroAnimations.initHero(); 22 }); 23 imgLoad.on('progress', function (instance) { 24 let currentCount = instance.progressedCount; 25 let totalCount = instance.images.length; 26 let progress = Math.round(currentCount * 100 / totalCount); 27 28 let progressElement = document.querySelector('.slogan__progress'); 29 progressElement.innerHTML = `${progress}%`; 30 31 let sloganTextElement = document.querySelector('.slogan__text'); 32 sloganTextElement.style.clipPath = `inset(0 ${100 - progress}% 0 0)`; 33 34 let sloganBackElement = document.querySelector('.slogan__back'); 35 sloganBackElement.style.clipPath = `inset(0 0 0 ${progress}%)`; 36 }); 37 } 38 39 40 /* lang menu */ 41 let langMoreTrigger = document.querySelector(".js-lang-more-trigger"); 42 if (langMoreTrigger) { 43 langMoreTrigger.addEventListener("click", function (event) { 44 event.preventDefault(); 45 46 let langMore = langMoreTrigger.closest(".js-lang-more"); 47 if (langMore.classList.contains('menu__item--active')) { 48 langMore.classList.remove('menu__item--active'); 49 } else { 50 langMore.classList.add('menu__item--active'); 51 } 52 53 return false; 54 }); 55 56 document.addEventListener('click', function (event) { 57 let isLangDropdown = false; 58 59 if (event.target.classList.contains('.js-lang-more') || event.target.closest(".js-lang-more")) { 60 isLangDropdown = true; 61 } 62 63 if (!isLangDropdown) { 64 document.querySelector(".js-lang-more").classList.remove('menu__item--active'); 65 } 66 }); 67 } 68 69 70 /* search */ 71 let searchTrigger = document.querySelector(".js-search-trigger"); 72 let searchPopup = document.querySelector(".js-search-popup"); 73 let searchPopupCloser = searchPopup.querySelector(".js-popup-close"); 74 let searchPopupContent = searchPopup.querySelector(".js-popup-content"); 75 76 searchTrigger.addEventListener('click', function (event) { 77 event.preventDefault(); 78 searchPopup.classList.add("popup--active"); 79 utility.disableScroll(); 80 }); 81 82 searchPopup.addEventListener('click', function (event) { 83 if (!searchPopupContent.contains(event.target)) { 84 searchPopup.classList.remove('popup--active'); 85 utility.enableScroll(); 86 } 87 }); 88 89 90 /* main menu */ 91 let mainMenu = document.querySelector('.js-main-menu'); 92 let mainMenuItems = [].slice.call(mainMenu.querySelectorAll('.menu__item')); 93 const mainMenuInTime = 100; 94 const mainMenuOutTime = 300; 95 let mainMenuInTimeout = null; 96 let mainMenuOutTimeout = null; 97 98 mainMenuItems.forEach(function (mainMenuItem) { 99 mainMenuItem.addEventListener('touchend', function (event) { 100 let currentMenu = event.target; 101 if (!currentMenu.classList.contains('menu__item')) { 102 currentMenu = event.target.closest('.menu__item'); 103 } 104 105 if (currentMenu.classList.contains('menu__item--selected')) { 106 event.stopPropagation(); 107 return true; 108 } else { 109 event.stopPropagation(); 110 event.preventDefault(); 111 mainMenuItems.forEach(function (mainMenuItem) { 112 mainMenuItem.classList.remove('menu__item--selected'); 113 }); 114 115 currentMenu.classList.add('menu__item--selected'); 116 117 let subMenu = currentMenu.querySelector('.menu__item--content'); 118 if (subMenu) { 119 let subMenuPosition = subMenu.getBoundingClientRect(); 120 subMenu.style.setProperty('--left', `-${subMenuPosition.left}px`); 121 subMenu.style.setProperty('--right', `-${document.body.clientWidth - subMenuPosition.right}px`); 122 } 123 } 124 return false; 125 }); 126 127 mainMenuItem.addEventListener('mouseenter', function (event) { 128 clearTimeout(mainMenuInTimeout); 129 clearTimeout(mainMenuOutTimeout); 130 mainMenuInTimeout = setTimeout(function () {
131 mainMenuItems.forEach(function (mainMenuItem) { 132 mainMenuItem.classList.remove('menu__item--selected'); 133 }); 134 135 let currentMenu = event.target; 136 currentMenu.classList.add('menu__item--selected'); 137 138 let subMenu = currentMenu.querySelector('.menu__item--content'); 139 if (subMenu) { 140 let subMenuPosition = subMenu.getBoundingClientRect(); 141 subMenu.style.setProperty('--left', `-${subMenuPosition.left}px`); 142 subMenu.style.setProperty('--right', `-${document.body.clientWidth - subMenuPosition.right}px`); 143 } 144 }, mainMenuInTime); 145 }); 146 }); 147 148 mainMenu.addEventListener('mouseleave', function () { 149 clearTimeout(mainMenuInTimeout); 150 clearTimeout(mainMenuOutTimeout); 151 mainMenuOutTimeout = setTimeout(function () { 152 mainMenuItems.forEach(function (mainMenuItem) { 153 mainMenuItem.classList.remove('menu__item--selected'); 154 }); 155 }, mainMenuOutTime); 156 }); 157 158 document.addEventListener('touchend', function (event) { 159 if (!event.target.closest('.js-main-menu') && event.target != mainMenu) { 160 mainMenuItems.forEach(function (mainMenuItem) { 161 mainMenuItem.classList.remove('menu__item--selected'); 162 }); 163 } 164 }); 165 166 167 /* mobile menu */ 168 let mobileMenu = document.querySelector(".js-mobile-menu"); 169 let mobileMenuTrigger = document.querySelector(".js-mobile-menu-trigger"); 170 let mobileMenuCloser = document.querySelector(".js-mobile-menu-close"); 171 let mobileMenuFlag = 0; 172 let mobileMenuNavArrows = [].slice.call(document.querySelectorAll('.js-mobile-menu-nav-arrow')); 173 let mobileMenuNavWrapper = document.querySelector(".js-mobile-menu-nav"); 174 let mobileMenuNavBg = document.querySelector(".js-mobile-menu-back"); 175 176 mobileMenuTrigger.addEventListener('click', function (event) { 177 mobileMenu.classList.add('active'); 178 utility.disableScroll(); 179 }); 180 181 mobileMenuNavBg.addEventListener('click', function () { 182 mobileMenu.classList.remove('active'); 183 utility.enableScroll(); 184 185 mobileMenuNavArrows.forEach(function (mobileMenuNavArrow) { 186 mobileMenuNavWrapper.classList.remove('hide'); 187 let parentLi = mobileMenuNavArrow.parentNode; 188 let parentLiContent = parentLi.getElementsByClassName('menu__item--content section__wrapper')[0]; 189 parentLiContent.classList.remove('active'); 190 }); 191 mobileMenuFlag = 0; 192 }); 193 194 mobileMenuCloser.addEventListener('click', function () { 195 if (mobileMenuFlag == 0) { 196 mobileMenu.classList.remove('active'); 197 utility.enableScroll(); 198 } else { 199 mobileMenuNavArrows.forEach(function (mobileMenuNavArrow) { 200 mobileMenuNavWrapper.classList.remove('hide'); 201 let parentLi = mobileMenuNavArrow.parentNode; 202 let parentLiContent = parentLi.getElementsByClassName('menu__item--content section__wrapper')[0]; 203 parentLiContent.classList.remove('active'); 204 }); 205 mobileMenuFlag--; 206 } 207 }); 208 209 mobileMenuNavArrows.forEach(function (mobileMenuNavArrow) { 210 mobileMenuNavArrow.addEventListener('click', function () { 211 mobileMenuNavWrapper.classList.add('hide'); 212 let parentLi = this.parentNode; 213 let parentLiContent = parentLi.getElementsByClassName('menu__item--content section__wrapper')[0]; 214 parentLiContent.classList.add('active'); 215 mobileMenuFlag++; 216 }); 217 }); 218 219 220 /* video */ 221 let pageVideos = [].slice.call(document.querySelectorAll('video')); 222 let videoObserver = new IntersectionObserver(videoObserverCallback); 223 224 pageVideos.forEach(function (pageVideo) { 225 videoObserver.observe(pageVideo); 226 let videoSource = pageVideo.querySelector('source'); 227 if (!videoSource) { 228 addVideoSource(pageVideo); 229 } 230 }); 231 232 function videoObserverCallback (videoEntries) { 233 videoEntries.forEach(function (videoEntry) { 234 let videoElement = videoEntry.target; 235 if (videoEntry.isIntersecting) { 236 if (videoElement.loop || !videoElement.ended) { 237 videoElement.play(); 238 } 239 } else { 240 videoElement.pause(); 241 } 242 }); 243 } 244 245 function addVideoSource (videoElement) { 246 let videoTabletWidth = typeof videoElement.dataset.tablet != 'undefined' ? videoElement.dataset.tablet : null; 247 let videoMobileWidth = typeof videoElement.dataset.mobile != 'undefined' ? videoElement.dataset.mobile : null; 248 249 let videoURL = null; 250 let posterURL = null; 251 252 /* mobile video */ 253 if (videoMobileWidth && screen.width <= videoMobileWidth) { 254 videoURL = typeof videoElement.dataset.videoMobile != 'undefined' ? videoElement.dataset.videoMobile : videoURL; 255 posterURL = typeof videoElement.dataset.posterMobile != 'undefined' ? videoElement.dataset.posterMobile : posterURL; 256 } 257 258 /* tablet video */ 259 if (!videoURL && videoTabletWidth && screen.width <= videoTabletWidth) { 260 videoURL = typeof videoElement.dataset.videoTablet != 'undefined' ? videoElement.dataset.videoTablet : videoURL; 261 } 262 if (!posterURL && videoTabletWidth && screen.width <= videoTabletWidth) { 263 posterURL = typeof videoElement.dataset.posterTablet != 'undefined' ? videoElement.dataset.posterTablet : posterURL; 264 } 265 266 /* desktop video */ 267 if (!videoURL) { 268 videoURL = typeof videoElement.dataset.video != 'undefined' ? videoElement.dataset.video : videoURL; 269 } 270 if (!posterURL) { 271 posterURL = typeof videoElement.dataset.poster != 'undefined' ? videoElement.dataset.poster : posterURL; 272 } 273 274 let videoSources = ""; 275 if (videoURL) { 276 videoSources += '<source src="' + videoURL + '" type="video/mp4">'; 277 } 278 videoElement.innerHTML = videoSources; 279 if (!videoElement.poster) { 280 videoElement.poster = posterURL; 281 } 282 283 videoElement.parentElement.classList.add('loading'); 284 videoElement.addEventListener('playing', function () { 285 videoElement.parentElement.classList.remove('loading'); 286 }); 287 } 288 289 290 /* 3D hover effect */ 291 let hover3dTargets = [].slice.call(document.querySelectorAll('.js-hover-3d')); 292 const motionMatchMedia = window.matchMedia("(prefers-reduced-motion)"); 293 const THRESHOLD = 10; 294 const EASING = 0.025; 295 296 if (!utility.isTouchDevice() && !motionMatchMedia.matches) {
297 hover3dTargets.forEach(function (hover3dTarget) { 298 let state = Object.create(null); 299 state.rafId = null; 300 state.rotateX = 0; 301 state.rotateY = 0; 302 state.scale = 1; 303 state.mouseX = hover3dTarget.clientWidth / 2; 304 state.mouseY = hover3dTarget.clientHeight / 2; 305 state.translationX = 0; 306 state.translationY = 0; 307 state.translationScale = 1; 308 state.translationMouseX = 0; 309 state.translationMouseY = 0; 310 311 hover3dTarget.addEventListener("mousemove", function (event) { 312 update(event); 313 state.scale = 1.1; 314 315 if (!state.rafId) { 316 state.rafId = window.requestAnimationFrame(paint); 317 } 318 }); 319 hover3dTarget.addEventListener("mouseleave", function (event) { 320 reset(event); 321 }); 322 323 function paint () { 324 state.translationX = utility.lerp(state.translationX, state.rotateX, EASING); 325 state.translationY = utility.lerp(state.translationY, state.rotateY, EASING); 326 state.translationScale = utility.lerp(state.translationScale, state.scale, EASING); 327 state.translationMouseX = utility.lerp(state.translationMouseX, utility.lineEq(-20, 20, state.clientWidth, 0, state.mouseX), EASING); 328 state.translationMouseY = utility.lerp(state.translationMouseY, utility.lineEq(-20, 20, state.clientHeight, 0, state.mouseY), EASING); 329 330 gsap.set(hover3dTarget, { 331 x: state.translationMouseX, 332 y: state.translationMouseY, 333 transform: `perspective(${state.clientWidth}px) rotateX(${state.translationY}deg) rotateY(${state.translationX}deg) scale3d(${state.translationScale}, ${state.translationScale}, ${state.translationScale})` 334 }); 335 336 state.rafId = window.requestAnimationFrame(paint); 337 } 338 339 function update (event) { 340 let clientX = event.clientX; 341 let clientY = event.clientY; 342 let clientWidth = event.currentTarget.clientWidth; 343 let clientHeight = event.currentTarget.clientHeight; 344 let targetPosition = event.currentTarget.parentElement.getBoundingClientRect(); 345 let offsetLeft = targetPosition.left; 346 let offsetTop = targetPosition.top; 347 348 let horizontal = (clientX - offsetLeft) / clientWidth; 349 let vertical = (clientY - offsetTop) / clientHeight; 350 let rotateX = (THRESHOLD / 2 - horizontal * THRESHOLD).toFixed(2); 351 let rotateY = (vertical * THRESHOLD - THRESHOLD / 2).toFixed(2); 352 353 state.clientWidth = clientWidth; 354 state.clientHeight = clientHeight; 355 state.rotateX = rotateX; 356 state.rotateY = rotateY; 357 state.mouseX = clientX - offsetLeft; 358 state.mouseY = clientY - offsetTop; 359 } 360 361 function reset (event) { 362 state.clientWidth = event.currentTarget.clientWidth; 363 state.clientHeight = event.currentTarget.clientHeight; 364 state.rotateX = 0; 365 state.rotateY = 0; 366 state.mouseX = event.currentTarget.clientWidth / 2; 367 state.mouseY = event.currentTarget.clientHeight / 2; 368 state.scale = 1; 369 } 370 }); 371 } 372 373 374 /* video mouse follower */ 375 let videoCursor = document.querySelector('.js-video-cursor'); 376 if (videoCursor && !utility.isTouchDevice()) { 377 let cursorTarget = videoCursor.closest('.banner__video-wrapper'); 378 if (cursorTarget) { 379 cursorTarget.addEventListener("mousemove", function (event) { 380 let targetPosition = event.currentTarget.parentElement.getBoundingClientRect(); 381 let offsetLeft = targetPosition.left; 382 let offsetTop = targetPosition.top; 383 let mouseX = event.clientX - offsetLeft; 384 let mouseY = event.clientY - offsetTop; 385 videoCursor.style.left = mouseX + "px"; 386 videoCursor.style.top = mouseY + "px"; 387 videoCursor.classList.add('banner__cursor--visible'); 388 }); 389 390 cursorTarget.addEventListener("mouseleave", function () { 391 videoCursor.classList.remove('banner__cursor--visible'); 392 }); 393 394 cursorTarget.addEventListener("click", function () { 395 videoCursor.classList.add('banner__cursor--active'); 396 397 setTimeout(function () { 398 videoCursor.classList.remove('banner__cursor--active'); 399 }, 500); 400 }); 401 } 402 } 403 404 405 /* YouTube video popup */ 406 let videoBanner = document.querySelector('.js-video-banner'); 407 let videoBannerPopup, videoBannerPopupContact, videoBannerPopupCloser, backgroundVideo, YTScriptTag, firstScriptTag,
408 player, YTVideoId, playerHeight, playerWidth, playerRatio; 409 if (videoBanner) { 410 videoBannerPopup = document.querySelector('.js-video-popup'); 411 videoBannerPopupContact = document.querySelector('.js-video-popup-content'); 412 videoBannerPopupCloser = document.querySelector('.js-video-popup-close'); 413 backgroundVideo = videoBanner.querySelector('.banner__video'); 414 415 YTScriptTag = document.createElement('script'); 416 YTScriptTag.src = "https://www.youtube.com/iframe_api"; 417 firstScriptTag = document.getElementsByTagName('script')[0]; 418 firstScriptTag.parentNode.insertBefore(YTScriptTag, firstScriptTag); 419 420 player; 421 YTVideoId = videoBanner.dataset.youtube; 422 423 playerHeight = 0; 424 playerWidth = 0; 425 playerRatio = 16 / 9; 426 427 setSizes(true); 428 429 window.addEventListener('resize', utility.debounce(function () { 430 setSizes(false); 431 }, 250)); 432 433 videoBanner.addEventListener('touchend', function (event) { 434 event.preventDefault(); 435 event.stopPropagation(); 436 437 videoBannerPopup.classList.add('banner__popup--active'); 438 utility.disableScroll(); 439 backgroundVideo.pause(); 440 player.playVideo(); 441 442 if (videoCursor && utility.isTouchDevice()) { 443 videoCursor.classList.add('banner__cursor--hidden'); 444 } 445 446 return false; 447 }); 448 449 videoBanner.addEventListener('click', function (event) { 450 event.preventDefault(); 451 452 videoBannerPopup.classList.add('banner__popup--active'); 453 utility.disableScroll(); 454 backgroundVideo.pause(); 455 player.playVideo(); 456 457 if (videoCursor && utility.isTouchDevice()) { 458 videoCursor.classList.add('banner__cursor--hidden'); 459 } 460 461 return false; 462 }); 463 464 videoBannerPopup.addEventListener('touchend', function (event) { 465 event.preventDefault(); 466 event.stopPropagation(); 467 468 if (event.target == event.currentTarget) { 469 videoBannerPopup.classList.remove('banner__popup--active'); 470 utility.enableScroll(); 471 backgroundVideo.play(); 472 player.pauseVideo(); 473 474 if (videoCursor && utility.isTouchDevice()) { 475 videoCursor.classList.remove('banner__cursor--hidden'); 476 } 477 } 478 479 return false; 480 }); 481 482 videoBannerPopup.addEventListener('click', function (event) { 483 event.preventDefault(); 484 485 if (event.target == event.currentTarget) { 486 videoBannerPopup.classList.remove('banner__popup--active'); 487 utility.enableScroll(); 488 backgroundVideo.play(); 489 player.pauseVideo(); 490 491 if (videoCursor && utility.isTouchDevice()) { 492 videoCursor.classList.remove('banner__cursor--hidden'); 493 } 494 } 495 496 return false; 497 }); 498 499 videoBannerPopupCloser.addEventListener('touchend', function (event) { 500 event.preventDefault(); 501 event.stopPropagation(); 502 503 videoBannerPopup.classList.remove('banner__popup--active'); 504 utility.enableScroll(); 505 backgroundVideo.play(); 506 player.pauseVideo(); 507 508 if (videoCursor && utility.isTouchDevice()) { 509 videoCursor.classList.remove('banner__cursor--hidden'); 510 } 511 512 return false; 513 }); 514 515 videoBannerPopupCloser.addEventListener('click', function (event) { 516 event.preventDefault(); 517 518 videoBannerPopup.classList.remove('banner__popup--active'); 519 utility.enableScroll(); 520 backgroundVideo.play(); 521 player.pauseVideo(); 522 523 if (videoCursor && utility.isTouchDevice()) { 524 videoCursor.classList.remove('banner__cursor--hidden'); 525 } 526 527 return false; 528 }); 529 530 function setSizes (initial) { 531 let hRate = 0.8; 532 let wRate = 0.8; 533 let wMargin = 0; 534 535 let windowRatio = window.innerWidth / window.innerHeight 536 if (windowRatio >= playerRatio) { 537 playerHeight = window.innerHeight * hRate; 538 playerWidth = playerHeight * playerRatio; 539 } else { 540 if (window.innerWidth <= 540) { 541 playerWidth = window.innerWidth - wMargin * 2; 542 } else { 543 playerWidth = window.innerWidth * wRate; 544 } 545 playerHeight = playerWidth / playerRatio; 546 } 547 548 if (!initial) { 549 player.setSize(playerWidth, playerHeight); 550 } 551 552 videoBannerPopup.querySelector('.banner__popup-wrapper').style.setProperty('--width', `${playerWidth}px`); 553 videoBannerPopup.querySelector('.banner__popup-wrapper').style.setProperty('--height', `${playerHe
553ight}px`); 554 } 555 556 function onYouTubeIframeAPIReady () { 557 player = new YT.Player(videoBannerPopupContact, { 558 height: playerHeight, 559 width: playerWidth, 560 videoId: YTVideoId, 561 playerVars: { 562 'autoplay': 0, 563 'cc_lang_pref': "ru", 564 'cc_load_policy': 0, 565 'controls': 1, 566 'disablekb': 0, 567 'fs': 1, 568 'hl': "ru", 569 'iv_load_policy': 3, 570 'loop': 0, 571 'modestbranding': 1, 572 'playsinline': 1 573 } 574 }); 575 } 576 } 577 578 579 /* question form */ 580 let questionForms = [].slice.call(document.querySelectorAll('.js-question-form')); 581 let phoneMask = new Inputmask({ 582 mask: "+7 (999) 999-99-99", 583 clearMaskOnLostFocus: true, 584 showMaskOnHover: false, 585 showMaskOnFocus: true, 586 insertMode: false, 587 insertModeVisual: false, 588 undoOnEscape: false, 589 positionCaretOnTab: true, 590 tabThrough: false, 591 shiftPositions: true, 592 positionCaretOnClick: "lvp", 593 inputmode: "tel", 594 oncomplete: function (event) { 595 event.target.classList.add('valid'); 596 event.target.classList.remove('error'); 597 }, 598 onincomplete: function (event) { 599 event.target.classList.remove('valid'); 600 event.target.classList.add('error'); 601 }, 602 oncleared: function (event) { 603 event.target.classList.remove('valid'); 604 event.target.classList.remove('error'); 605 }, 606 onKeyDown: function (event, buffer, caretPos, opts) { 607 if (['ArrowRight', 'ArrowDown', 'ArrowLeft', 'ArrowUp'].includes(event.key)) { 608 return false; 609 } 610 } 611 }); 612 questionForms.forEach(function (questionForm) { 613 questionForm.addEventListener('submit', questionFormHandle); 614 615 let questionFormPhone = questionForm.querySelector("INPUT[type='tel']"); 616 phoneMask.mask(questionFormPhone); 617 }); 618 619 function questionFormHandle (event) { 620 event.preventDefault(); 621 622 let form = event.target; 623 let data = new FormData(form); 624 let url = form.action; 625 626 let formPhone = form.querySelector("INPUT[type='tel']"); 627 if (formPhone.inputmask && formPhone.inputmask.unmaskedvalue() && !formPhone.inputmask.isComplete()) { 628 formPhone.classList.add('error'); 629 return; 630 } 631 if (formPhone.inputmask && !formPhone.inputmask.unmaskedvalue() && data.has(formPhone.name)) { 632 data.set(formPhone.name, ""); 633 } 634 635 let formEmail = form.querySelector("INPUT[data-type='email']"); 636 if (formEmail) { 637 if (formEmail.value) { 638 let validEmail = "[a-zа-Ñ0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zа-Ñ0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-zа-Ñ0-9](?:[a-zа-Ñ0-9-]*[a-zа-Ñ0-9])?\.)+[a-zа-Ñ0-9](?:[a-zа-Ñ0-9-]*[a-zа-Ñ0-9])?"; 639 let emailValid = formEmail.value.match(validEmail); 640 if (!emailValid) { 641 formEmail.classList.add("error"); 642 return; 643 } 644 } else { 645 formEmail.classList.add("error"); 646 return; 647 } 648 } 649 650 let request = new XMLHttpRequest(); 651 request.open("POST", url, true); 652 form.classList.add("callback-form--loading"); 653 request.onreadystatechange = function () { 654 if (request.readyState == XMLHttpRequest.DONE && request.status == 200) { 655 form.classList.remove("callback-form--loading"); 656 657 let parser = new DOMParser(); 658 let response = parser.parseFromString(request.responseText, 'text/html'); 659 660 let errors = response.querySelector('.js-form-errors'); 661 if (errors) { 662 let responseFormContent = response.querySelector('.js-question-form').innerHTML; 663 form.innerHTML = ""; 664 let processed = BX.processHTML(responseFormContent, false); 665 form.insertAdjacentHTML("afterBegin", processed.HTML); 666 console.log(processed); 667 BX.ajax.processScripts(processed.SCRIPT); 668 669 let questionFormPhone = form.querySelector("INPUT[type='tel']"); 670 phoneMask.mask(questionFormPhone); 671 672 return false; 673 } 674 675 let success = response.querySelector('.js-form-message'); 676 if (success) { 677 let responseFormContent = response.querySelector('.js-question-form').innerHTML; 678 form.innerHTML = ""; 679 let processed = BX.processHTML(responseFormContent, false); 680 form.insertAdjacentHTML("afterBegin", processed.HTML); 681 BX.ajax.processScripts(processed.SCRIPT); 682 form.style.display = "none"; 683 684 let formContent = form.closest('.js-form-content');
685 formContent.prepend(success); 686 687 let formSection = form.closest('.js-question-section'); 688 formSection.classList.add('section--callback-form-success'); 689 return false; 690 } 691 } 692 } 693 request.send(data); 694 695 return false; 696 } 697 698 699 /* restaurants section */ 700 let restaurantItems = [].slice.call(document.querySelectorAll(".js-restaurant-item")); 701 let restaurantBackgrounds = [].slice.call(document.querySelectorAll(".js-restaurant-bg")); 702 restaurantItems.forEach(function (restaurantItem) { 703 let currentItem = restaurantItem; 704 705 currentItem.addEventListener('mouseenter', function () { 706 restaurantItems.forEach(function (restaurantItem) { 707 restaurantItem.classList.remove('focus'); 708 }); 709 this.classList.add("focus"); 710 711 let index = restaurantItems.indexOf(this); 712 restaurantBackgrounds.forEach(function (restaurantBackground) { 713 restaurantBackground.classList.remove('active'); 714 }); 715 restaurantBackgrounds[index].classList.add("active"); 716 }); 717 718 currentItem.addEventListener('touchend', function (event) { 719 720 721 if (event.target.closest('.restaurants--item--btn')) { 722 event.stopPropagation(); 723 return true; 724 } else if (event.target.closest('.js-restaurant-item')) { 725 event.stopPropagation(); 726 event.preventDefault(); 727 728 restaurantItems.forEach(function (restaurantItem) { 729 restaurantItem.classList.remove('focus'); 730 }); 731 this.classList.add("focus"); 732 733 let index = restaurantItems.indexOf(this);
734 restaurantBackgrounds.forEach(function (restaurantBackground) { 735 restaurantBackground.classList.remove('active'); 736 }); 737 restaurantBackgrounds[index].classList.add("active"); 738 } 739 return false; 740 }); 741 }); 742 743 744 /* master classes filter */ 745 let filterNavItems = [].slice.call(document.querySelectorAll('.js-filter-nav-item')); 746 let filterItems = [].slice.call(document.querySelectorAll('.js-filter-item')); 747 let filterWrapper = document.querySelector('.js-filter-wrapper'); 748 let filterParams = []; 749 let filterList = Object.create(null); 750 751 if (filterWrapper) { 752 753 filterItems.forEach(function (filterItem) { 754 let itemIndex = filterItem.dataset.index; 755 itemIndex = utility.getRandomNumber(0, 9999); 756 filterList[itemIndex] = filterItem.cloneNode(true); 757 }); 758 759 filterWrapper.classList.add('masters-products--updating'); 760 filterFormatItems(filterWrapper, filterList, filterParams); 761 762 window.addEventListener('resize', function () { 763 filterWrapper.classList.add('masters-products--updating'); 764 }); 765 766 window.addEventListener('resize', utility.debounce(function () { 767 filterFormatItems(filterWrapper, filterList, filterParams); 768 }, 250)); 769 770 filterNavItems.forEach(function (filterNavItem) { 771 filterNavItem.addEventListener('click', function (event) { 772 event.preventDefault(); 773 774 let filterParam = event.target.dataset.param; 775 filterParams = []; 776 if (filterParam != "all") { 777 event.target.classList.add('page-filter__item--active'); 778 filterParams.push(filterParam); 779 } 780 781 if (!filterParams.length) { 782 filterNavItems.forEach(function (filterNavItem) { 783 if (filterNavItem.dataset.param == "all") { 784 filterNavItem.classList.add('page-filter__item--active'); 785 } else { 786 filterNavItem.classList.remove('page-filter__item--active'); 787 } 788 }); 789 } else { 790 filterNavItems.forEach(function (filterNavItem) { 791 if (filterNavItem.dataset.param == filterParams[0]) { 792 filterNavItem.classList.add('page-filter__item--active'); 793 } else { 794 filterNavItem.classList.remove('page-filter__item--active'); 795 } 796 }); 797 } 798 799 filterWrapper.classList.add('masters-products--updating'); 800 filterFormatItems(filterWrapper, filterList, filterParams); 801 return false; 802 }); 803 }); 804 } 805 806 807 Array.prototype.removeByValue = function () { 808 var what, a = arguments, L = a.length, ax; 809 while (L && this.length) { 810 what = a[--L]; 811 while ((ax = this.indexOf(what)) !== -1) { 812 this.splice(ax, 1); 813 } 814 } 815 return this; 816 }; 817 818 function filterFormatItems (filterWrapper, filterList, filterParams) { 819 820 // count columns 821 let columnCount = 1; 822 if (window.innerWidth > 600) { 823 columnCount = 2; 824 } 825 if (window.innerWidth > 800) { 826 columnCount = 3; 827 } 828 if (window.innerWidth > 1000) { 829 columnCount = 4; 830 } 831 832 // create columns 833 let columns = Object.create(null); 834 for (i = 0; i < columnCount; i++) { 835 let column = document.createElement('div'); 836 column.className = "masters-products__column"; 837 column.setAttribute('data-count', i); 838 columns[i] = column; 839 } 840 841 // fill columns 842 let itemNumber = 1; 843 for (itemIndex in filterList) { 844 let item = filterList[itemIndex].cloneNode(true); 845 let hideItem = false; 846 if (filterParams.length) { 847 hideItem = true; 848 filterParams.forEach(function (filterParam) { 849 if (typeof item.dataset[filterParam] != "undefined") { 850 hideItem = false; 851 } 852 }); 853 } 854 855 if (hideItem) { 856 continue; 857 } 858 859 if (filterWrapper.classList.contains('masters-products--another')) { 860 let highLightNumber = 2; 861 if (window.innerWidth > 800) { 862 highLightNumber = 3; 863 } 864 if (window.innerWidth > 1000) { 865 highLightNumber = 1; 866 } 867 if (itemNumber == highLightNumber) { 868 item.classList.add('masters-products__item--styled'); 869 } 870 } else { 871 if (itemNumber % 5 == 0) { 872 item.classList.add('masters-products__item--styled'); 873 } 874 } 875 876 877 columns[(itemNumber - 1) % columnCount].appendChild(item); 878 itemNumber++; 879 } 880 881 // replace filterWrapper with columns 882 while (filterWrapper.firstChild) { 883 filterWrapper.removeChild(filterWrapper.firstChild); 884 } 885 for (columnIndex in columns) { 886 filterWrapper.appendChild(columns[columnIndex]); 887 } 888 filterWrapper.classList.remove('masters-products--updating'); 889 filterWrapper.classList.add('masters-products--init'); 890 } 891 892 893 /* order form */ 894 let orderForm = { 895 wrapper: document.querySelector('.js-order-form'), 896 form: document.querySelector('.js-order-form-popup'), 897 selects: [].slice.call(document.querySelectorAll('.js-order-form-select')), 898 selectItems: [].slice.call(document.querySelectorAll('.js-order-form-select-item')), 899 selectInputs: [].slice.call(document.querySelectorAll('.js-order-form-select-input')), 900 datetime: document.querySelector('.js-order-form-datetime'), 901 dateInput: document.querySelector('.js-order-form-date'), 902 dateValue: document.querySelector('.js-order-form-date-value'), 903 timeTrigger: document.querySelector('.js-order-form-time-trigger'), 904 timeSlider: null, 905 timeItems: [].slice.call(document.querySelectorAll('.js-order-form-time-item')), 906 timeValue: document.querySelector('.js-order-form-time-value'), 907 timeInput: document.querySelector('.js-order-form-time-input'), 908 // payment: document.querySelector('.js-order-form-payment'), 909 // paymentToggle: document.querySelector('.js-order-form-payment-toggle'), 910 serviceToggles: [].slice.call(document.querySelectorAll('.js-order-form-service')), 911 popupTrigger: document.querySelector('.js-order-form-popup-trigger'), 912 popupWrapper: document.querySelector('.js-order-form-popup-wrapper'), 913 popupClosers: [].slice.call(document.querySelectorAll('.js-order-form-popup-close')), 914 totalPrice: document.querySelector('.js-order-form-total'), 915 adultCount: document.querySelector('.js-order-form-adult'), 916 childCount: document.querySelector('.js-order-form-child'), 917 body: document.querySelector('body'), 918 init: function () { 919 this.selectCloseHandler = this.selectCloseHandler.bind(this); 920 this.selectOpenHandler = this.selectOpenHandler.bind(this);
921 this.selectChooseHandler = this.selectChooseHandler.bind(this); 922 this.selectChangeHandler = this.selectChangeHandler.bind(this); 923 this.showDatePicker = this.showDatePicker.bind(this); 924 this.hideDatePicker = this.hideDatePicker.bind(this); 925 // this.changePaymentHandler = this.changePaymentHandler.bind(this); 926 this.timeTriggerClickHandler = this.timeTriggerClickHandler.bind(this); 927 this.timeItemClickHandler = this.timeItemClickHandler.bind(this); 928 this.formClickHandler = this.formClickHandler.bind(this); 929 this.changeServiceHandler = this.changeServiceHandler.bind(this); 930 this.updatePrice = this.updatePrice.bind(this); 931 this.formSubmit = this.formSubmit.bind(this); 932 this.openPopup = this.openPopup.bind(this); 933 this.popupClose = this.popupClose.bind(this); 934 this.clickPopupWrapperHandler = this.clickPopupWrapperHandler.bind(this); 935 this.resizeHandler = this.resizeHandler.bind(this); 936 937 this.initEvents(); 938 this.initDatePicker(); 939 this.initTimeSelect(); 940 this.initPhoneMask(); 941 this.updatePrice(); 942 }, 943 initEvents: function () { 944 let self = this; 945 946 if (this.selects) { 947 this.selects.forEach(function (select) { 948 select.addEventListener('click', self.selectOpenHandler); 949 }); 950 } 951 952 if (this.selectItems) { 953 this.selectItems.forEach(function (selectItem) { 954 selectItem.addEventListener('click', self.selectChooseHandler); 955 }); 956 } 957 958 if (this.selectInputs) { 959 this.selectInputs.forEach(function (selectInput) { 960 selectInput.addEventListener('change', self.selectChangeHandler); 961 }); 962 } 963 964 if (this.timeItems) { 965 this.timeItems.forEach(function (timeItem) { 966 timeItem.addEventListener('click', self.timeItemClickHandler); 967 }); 968 } 969 970 if (this.serviceToggles) { 971 this.serviceToggles.forEach(function (serviceToggle) { 972 serviceToggle.addEventListener('change', self.changeServiceHandler); 973 }); 974 } 975 976 if (this.timeTrigger) { 977 this.timeTrigger.addEventListener('click', self.timeTriggerClickHandler); 978 } 979 980 // if (this.payment) { 981 // this.payment.addEventListener('change', self.changePaymentHandler); 982 // } 983 984 if (this.popupTrigger) { 985 this.popupTrigger.addEventListener('click', self.openPopup); 986 } 987 988 if (this.popupWrapper) { 989 this.popupWrapper.addEventListener('click', self.clickPopupWrapperHandler); 990 } 991 992 if (this.popupClosers) { 993 this.popupClosers.forEach(function (popupCloser) { 994 popupCloser.addEventListener('click', self.popupClose); 995 }); 996 } 997 998 if (this.form) { 999 this.form.addEventListener('click', self.formClickHandler); 1000 this.form.addEventListener('submit', self.formSubmit); 1001 if (this.form.querySelector("INPUT[name='name']")) { 1002 this.form.querySelector("INPUT[name='name']").addEventListener('change', function () { 1003 if (!this.value) { 1004 this.classList.add("error"); 1005 this.classList.remove("valid"); 1006 } else { 1007 this.classList.remove("error"); 1008 this.classList.add("valid"); 1009 } 1010 }); 1011 } 1012 if (this.form.querySelector("INPUT[name='email']")) { 1013 this.form.querySelector("INPUT[name='email']").addEventListener('change', function () { 1014 if (this.value) { 1015 let validEmail = "[a-zа-Ñ0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zа-Ñ0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-zа-Ñ0-9](?:[a-zа-Ñ0-9-]*[a-zа-Ñ0-9])?\.)+[a-zа-Ñ0-9](?:[a-zа-Ñ0-9-]*[a-zа-Ñ0-9])?"; 1016 let emailValid = this.value.match(validEmail); 1017 if (!emailValid) { 1018 this.classList.add("error"); 1019 this.classList.remove("valid"); 1020 } else { 1021 this.classList.remove("error"); 1022 this.classList.add("valid"); 1023 } 1024 } else { 1025 this.classList.add("error"); 1026 this.classList.remove("valid"); 1027 } 1028 }); 1029 } 1030 } 1031 1032 this.body.addEventListener('click', self.selectCloseHandler); 1033 1034 window.addEventListener('resize', utility.debounce(this.resizeHandler, 250)); 1035 }, 1036 resizeHandler: function () { 1037 if (window.innerWidth > 800) { 1038 this.form.style.transition = ""; 1039 } else { 1040 this.form.style.transition = "opacity 0.3s ease-in-out, transform 0.3s ease-in-out"; 1041 } 1042 }, 1043 initDatePicker: function () { 1044 if (!this.dateInput) { 1045 return false; 1046 } 1047 let self = this; 1048 let startDay = new Date(Date.now() + 1000 * 60 * 60 * 24 * 1); 1049 let endDay = new Date(Date.now() + 1000 * 60 * 60 * 24 * 14); 1050 if (self.form.dataset.type == "master-class") { 1051 endDay = null; 1052 } 1053 1054 this.picker = datepicker(this.dateInput, { 1055 onSelect: function (instance, date) { 1056 self.dateValue.innerText = date.toLocaleDateString('ru-RU'); 1057 1058 self.form.querySelector(".order-form__datetime-item[data-type='date']").classList.remove("error"); 1059 1060 self.updatePrice(); 1061 }, 1062 onShow: function () { 1063 self.showDatePicker(); 1064 }, 1065 onHide: function () { 1066 self.hideDatePicker(); 1067 }, 1068 formatter: function (input, date, instance) { 1069 const value = date.toLocaleDateString('ru-RU'); 1070 input.value = value; 1071 }, 1072 position: "bl", 1073 startDay: 1, 1074 customDays: ['ÐÑ', 'Ðн', 'ÐÑ', 'СÑ', 'ЧÑ', 'ÐÑ', 'Сб'], 1075 customMonths: ['ЯнваÑÑ', 'ФевÑалÑ', 'ÐаÑÑ', 'ÐпÑелÑ', 'Ðай', 'ÐÑнÑ', 'ÐÑлÑ', 'ÐвгÑÑÑ', 'СенÑÑбÑÑ', 'ÐкÑÑбÑÑ', 'ÐоÑбÑÑ', 'ÐекабÑÑ'], 1076 defaultView: "calendar", 1077 overlayButton: "ÐÑбÑаÑÑ", 1078 overlayPlaceholder: "УкажиÑе год (4 ÑиÑÑÑ)", 1079 alwaysShow: false, 1080 minDate: startDay, 1081 maxDate: endDay, 1082 showAllDates: false, 1083 disableMobile: false, 1084 disableYearOverlay: true, 1085 disabledDates: [ 1086 new Date(2025, 0, 1) // ЯнваÑÑ = 0, Ñак как меÑÑÑÑ Ð² JavaScript наÑинаÑÑÑÑ Ñ 0 1087 ] 1088 }); 1089 }, 1090 initTimeSelect: function () { 1091 this.timeSlider = new Swiper('.js-order-form-time-slider', { 1092 direction: 'vertical', 1093 loop: false, 1094 speed: 300, 1095 slidesPerView: 5, 1096 slidesPerGroup: 5, 1097 navigation: { 1098 nextEl: '.js-order-form-time-next', 1099 prevEl: '.js-order-form-time-prev', 1100 } 1101 }); 1102 }, 1103 initPhoneMask: function () { 1104 let phoneMask = new Inputmask({ 1105 mask: "+7 (999) 999-99-99", 1106 clearMaskOnLostFocus: true, 1107 showMaskOnHover: false, 1108 showMaskOnFocus: true, 1109 insertMode: false, 1110 insertModeVisual: false, 1111 undoOnEscape: false, 1112 positionCaretOnTab: true, 1113 tabThrough: false, 1114 shiftPositions: true, 1115 positionCaretOnClick: "lvp", 1116 inputmode: "tel", 1117 oncomplete: function (event) {
1118 event.target.classList.add('valid'); 1119 event.target.classList.remove('error'); 1120 }, 1121 onincomplete: function (event) { 1122 event.target.classList.remove('valid'); 1123 event.target.classList.add('error'); 1124 }, 1125 oncleared: function (event) { 1126 event.target.classList.remove('valid'); 1127 event.target.classList.remove('error'); 1128 }, 1129 onKeyDown: function (event, buffer, caretPos, opts) { 1130 if (['ArrowRight', 'ArrowDown', 'ArrowLeft', 'ArrowUp'].includes(event.key)) { 1131 return false; 1132 } 1133 } 1134 }); 1135 let formPhone = this.form.querySelector("INPUT[name='phone']"); 1136 if (formPhone) { 1137 phoneMask.mask(formPhone); 1138 } 1139 }, 1140 selectOpenHandler: function (event) { 1141 event.preventDefault(); 1142 1143 let currentSelect = event.target; 1144 if (!currentSelect.classList.contains('js-order-form-select')) { 1145 currentSelect = currentSelect.closest('.js-order-form-select'); 1146 } 1147 1148 if (currentSelect.classList.contains('order-form__count-select--active')) { 1149 return; 1150 } 1151 1152 this.selects.forEach(function (select) { 1153 select.classList.remove('order-form__count-select--active'); 1154 let selectIcon = select.querySelector('.js-order-form-select-icon'); 1155 let selectInput = select.querySelector('.js-order-form-select-input'); 1156 if (selectIcon) { 1157 selectIcon.classList.remove('icon--chevron-up'); 1158 if (selectInput && selectInput.value != "0") { 1159 selectIcon.classList.add('icon--chevron-down'); 1160 } else { 1161 selectIcon.classList.add('icon--plus'); 1162 } 1163 } 1164 }); 1165 1166 if (!currentSelect.classList.contains('order-form__count-select--active')) { 1167 currentSelect.classList.add('order-form__count-select--active'); 1168 let currentSelectIcon = currentSelect.querySelector('.js-order-form-select-icon'); 1169 if (currentSelectIcon) { 1170 currentSelectIcon.classList.remove('icon--chevron-down'); 1171 currentSelectIcon.classList.remove('icon--plus'); 1172 currentSelectIcon.classList.add('icon--chevron-up'); 1173 } 1174 } 1175 }, 1176 selectCloseHandler: function (event) { 1177 let select = event.target; 1178 if (select.classList.contains('js-order-form-select-item')) { 1179 select = null; 1180 } else if (!select.classList.contains('js-order-form-select')) { 1181 select = select.closest('.js-order-form-select'); 1182 } 1183 1184 if (!select && this.selects) { 1185 this.selects.forEach(function (select) { 1186 select.classList.remove('order-form__count-select--active'); 1187 let selectIcon = select.querySelector('.js-order-form-select-icon'); 1188 let selectInput = select.querySelector('.js-order-form-select-input'); 1189 if (selectIcon) { 1190 selectIcon.classList.remove('icon--chevron-up'); 1191 if (selectInput && selectInput.value != "0") { 1192 selectIcon.classList.add('icon--chevron-down'); 1193 } else { 1194 selectIcon.classList.add('icon--plus'); 1195 } 1196 } 1197 }); 1198 } 1199 }, 1200 selectChooseHandler: function (event) { 1201 event.preventDefault(); 1202 1203 let selectItemValue = parseInt(event.target.innerText); 1204 let select = event.target.closest('.js-order-form-select'); 1205 let selectInput = select.querySelector('.js-order-form-select-input'); 1206 let selectIcon = select.querySelector('.js-order-form-select-icon'); 1207 1208 this.selects.forEach(function (select) { 1209 select.classList.remove("error"); 1210 }); 1211 1212 select.classList.remove('order-form__count-select--active'); 1213 select.classList.add('order-form__count-select--selected'); 1214 1215 if (selectInput) { 1216 selectInput.value = selectItemValue; 1217 } 1218 1219 if (selectIcon) { 1220 selectIcon.classList.remove('icon--chevron-up'); 1221 selectIcon.classList.add('icon--chevron-down'); 1222 } 1223 1224 if (selectItemValue == 0) { 1225 select.classList.remove('order-form__count-select--selected'); 1226 selectIcon.classList.remove('icon--chevron-up'); 1227 selectIcon.classList.add('icon--plus'); 1228 } 1229 1230 this.updatePrice(); 1231 }, 1232 selectChangeHandler: function (event) { 1233 event.preventDefault(); 1234 1235 let input = event.target; 1236 let inputValue = parseInt(event.target.value); 1237 let inputMax = parseInt(event.target.dataset.max); 1238 let select = event.target.closest('.js-order-form-select'); 1239 let selectIcon = select.querySelector('.js-order-form-select-icon'); 1240
1241 this.selects.forEach(function (select) { 1242 select.classList.remove("error"); 1243 }); 1244 1245 if (isNaN(inputValue)) { 1246 inputValue = 0; 1247 } 1248 1249 if (!isNaN(inputMax) && inputValue > inputMax) { 1250 inputValue = inputMax; 1251 } 1252 1253 input.value = inputValue; 1254 1255 if (inputValue == 0) { 1256 select.classList.remove('order-form__count-select--selected'); 1257 selectIcon.classList.remove('icon--chevron-up'); 1258 selectIcon.classList.add('icon--plus'); 1259 } 1260 1261 this.updatePrice(); 1262 }, 1263 showDatePicker: function () { 1264 this.datetime.classList.add('order-form__datetime--active'); 1265 this.datetime.classList.add('order-form__datetime--active-date'); 1266 this.datetime.classList.remove('order-form__datetime--active-time'); 1267 }, 1268 hideDatePicker: function () { 1269 this.datetime.classList.remove('order-form__datetime--active'); 1270 this.datetime.classList.remove('order-form__datetime--active-date'); 1271 }, 1272 // changePaymentHandler: function (event) { 1273 // let paymentCheckbox = event.target; 1274 1275 // if (!this.paymentToggle) { 1276 // return; 1277 // } 1278 1279 // if (paymentCheckbox.checked) { 1280 // this.paymentToggle.classList.add('toggle--active'); 1281 // } else { 1282 // this.paymentToggle.classList.remove('toggle--active'); 1283 // } 1284 // }, 1285 timeTriggerClickHandlerORIG: function (event) { 1286 let self = this; 1287 1288 setTimeout(function () { 1289 self.datetime.classList.add('order-form__datetime--active'); 1290 self.datetime.classList.add('order-form__datetime--active-time'); 1291 self.timeSlider.update(); 1292 }, 0); 1293 }, 1294 timeTriggerClickHandler: function (event) { 1295 let self = this; 1296 1297 setTimeout(function () { 1298 self.datetime.classList.add('order-form__datetime--active'); 1299 self.datetime.classList.add('order-form__datetime--active-time'); 1300 self.timeSlider.update(); 1301 1302 // ÐÑовеÑÑем даÑÑ: еÑли 31 декабÑÑ 2024, ÑкÑÑваем вÑÐµÐ¼Ñ Ð¿Ð¾Ñле 14:00 1303 if (self.dateInput.value === '31.12.2024') { 1304 self.timeItems.forEach(function (timeItem) { 1305 // ÐÑедполагаем, ÑÑо ÑлеменÑÑ Ð²Ñемени ÑодеÑÐ¶Ð°Ñ ÑекÑÑ Ð²Ð¸Ð´Ð° "14:30", "15:00" и Ñ.д. 1306 let timeValue = timeItem.innerText.trim(); 1307 if (timeValue > '14:00') { 1308 // СкÑÑваем ÑлеменÑÑ, еÑли вÑÐµÐ¼Ñ Ð¿Ð¾Ð·Ð¶Ðµ 14:00 1309 timeItem.style.display = 'none'; 1310 } else { 1311 // УбеждаемÑÑ, ÑÑо оÑÑалÑнÑе ÑлеменÑÑ Ð¾ÑобÑажаÑÑÑÑ 1312 timeItem.style.display = ''; 1313 } 1314 }); 1315 } else { 1316 // ÐÑли даÑа не 31.12.2024, показÑваем вÑе ÑлеменÑÑ Ð²Ñемени 1317 self.timeItems.forEach(function (timeItem) { 1318 timeItem.style.display = ''; 1319 }); 1320 } 1321 }, 0); 1322 }, 1323 formClickHandler: function (event) { 1324 let self = this; 1325 1326 let isDateTime = event.target.closest('.js-order-form-datetime'); 1327 setTimeout(function () { 1328 if (!isDateTime) { 1329 self.datetime.classList.remove('order-form__datetime--active'); 1330 self.datetime.classList.remove('order-form__datetime--active-time'); 1331 self.datetime.classList.remove('order-form__datetime--active-date'); 1332 } 1333 }, 0); 1334 }, 1335 timeItemClickHandler: function (event) { 1336 let self = this; 1337 let item = event.target; 1338 1339 self.form.querySelector(".order-form__datetime-item[data-type='time']").classList.remove("error"); 1340 1341 self.datetime.classList.remove('order-form__datetime--active'); 1342 self.datetime.classList.remove('order-form__datetime--active-time'); 1343 self.datetime.classList.remove('order-form__datetime--active-date'); 1344 1345 self.timeValue.innerText = item.innerText; 1346 self.timeInput.value = item.innerText; 1347 self.timeTrigger.classList.add('order-form__datetime-item--active'); 1348 }, 1349 updatePrice: function () { 1350 let self = this; 1351 1352 // total price 1353 let total = 0; 1354 if (self.selectInputs.length > 1) { 1355 let hasOverflow = false; 1356 self.selectInputs.forEach(function (selectInput) { 1357 let count = parseInt(selectInput.value); 1358 let min = parseInt(selectInput.dataset.min); 1359 if (count >= min) { 1360 hasOverflow = true; 1361 return; 1362 } 1363 }); 1364 1365 if (hasOverflow) {
1366 self.selectInputs.forEach(function (selectInput) { 1367 let count = parseInt(selectInput.value); 1368 let price = parseInt(selectInput.dataset.price); 1369 total += price * count; 1370 }); 1371 } else { 1372 let adultPrice = parseInt(self.selectInputs[0].dataset.price); 1373 let adultCount = parseInt(self.selectInputs[0].value); 1374 let adultMin = parseInt(self.selectInputs[0].dataset.min); 1375 let childPrice = parseInt(self.selectInputs[1].dataset.price); 1376 let childCount = parseInt(self.selectInputs[1].value); 1377 let minTotal = adultPrice * adultMin; 1378 1379 if (adultCount + childCount <= adultMin) { 1380 adultCount = adultCount + childCount; 1381 childCount = 0; 1382 } else { 1383 childCount = childCount - (adultMin - adultCount); 1384 adultCount = adultMin; 1385 } 1386 1387 total += adultPrice * adultCount + childPrice * childCount; 1388 1389 if (total < minTotal) { 1390 total = minTotal; 1391 } 1392 } 1393 } else { 1394 let minTotal = 0; 1395 self.selectInputs.forEach(function (selectInput) { 1396 let count = parseInt(selectInput.value); 1397 let price = parseInt(selectInput.dataset.price); 1398 let min = parseInt(selectInput.dataset.min); 1399 1400 minTotal = price * min; 1401 total += price * count; 1402 }); 1403 if (total < minTotal) { 1404 total = minTotal; 1405 } 1406 } 1407 1408 self.serviceToggles.forEach(function (serviceToggle) { 1409 if (serviceToggle.checked) { 1410 total += parseInt(serviceToggle.dataset.price); 1411 } 1412 }); 1413 if (self.totalPrice) { 1414 self.totalPrice.innerText = total + " â½"; 1415 } 1416 1417 // adult & child count 1418 self.selectInputs.forEach(function (selectInput) { 1419 if (selectInput.name == "count[adult]") { 1420 if (self.adultCount) { 1421 if (selectInput.value > 0) { 1422 self.adultCount.closest('.order-form__summary-item').classList.remove('order-form__summary-item--disabled'); 1423 self.adultCount.innerText = selectInput.value; 1424 } else { 1425 self.adultCount.closest('.order-form__summary-item').classList.add('order-form__summary-item--disabled'); 1426 self.adultCount.innerText = ""; 1427 } 1428 } 1429 } else if (selectInput.name == "count[child]") { 1430 if (self.childCount) { 1431 if (selectInput.value > 0) { 1432 self.childCount.closest('.order-form__summary-item').classList.remove('order-form__summary-item--disabled'); 1433 self.childCount.innerText = selectInput.value; 1434 } else { 1435 self.childCount.closest('.order-form__summary-item').classList.add('order-form__summary-item--disabled'); 1436 self.childCount.innerText = ""; 1437 } 1438 } 1439 } 1440 }); 1441 }, 1442 changeServiceHandler: function () { 1443 this.updatePrice(); 1444 }, 1445 formSubmit: function (event) { 1446 event.preventDefault(); 1447 1448 let self = this; 1449 let form = self.form; 1450 let data = Object.create(null); 1451 let hasErrors = false; 1452 1453 // check can buy 1454 let formCanBuyInput = form.querySelector(".js-order-form-can-buy"); 1455 data.can_buy = formCanBuyInput.value; 1456 1457 // check type 1458 let formTypeInput = form.querySelector(".js-order-form-type"); 1459 data.type = formTypeInput.value; 1460 1461 // check back url 1462 let formBackUrlInput = form.querySelector(".js-order-form-back-url"); 1463 data.back_url = formBackUrlInput.value; 1464 1465 // check title|name 1466 let formTitleInput = form.querySelector(".js-order-form-title"); 1467 data.title = formTitleInput.value; 1468 1469 // check counts 1470 data.counts = Object.create(null); 1471 let formAdultCountInput = form.querySelector("INPUT[name='count[adult]']"); 1472 let formAdultCount = formAdultCountInput.closest('.order-form__count-select'); 1473 let formChildCountInput = form.querySelector("INPUT[name='count[child]']"); 1474 let formChildCount = null; 1475 1476 if (formChildCountInput) { 1477 formChildCount = formChildCountInput.closest('.order-form__count-select'); 1478 if (!parseInt(formAdultCountInput.value) && !parseInt(formChildCountInput.value)) { 1479 formAdultCount.classList.add("error"); 1480 formChildCount.classList.add("error"); 1481 hasErrors = true; 1482 } else { 1483 if (parseInt(formAdultCountInput.value)) { 1484 data.counts.adult = Object.create(null); 1485 data.counts.adult.qty = parseInt(formAdultCountInput.value); 1486 data.counts.adult.id = formAdultCountInput.dataset.id; 1487 data.counts.adult.price = parseInt(formAdultCountInput.dataset.price); 1488 data.counts.adult.min = parseInt(formAdultCountInput.dataset.min); 1489 } 1490 if (parseInt(formChildCountInput.value)) { 1491 data.counts.child = Object.create(null); 1492 data.counts.child.qty = parseInt(formChildCountInput.value); 1493 data.counts.child.id = formChildCountInput.dataset.id; 1494 data.counts.child.price = parseInt(formChildCountInput.dataset.price); 1495 data.counts.child.min = parseInt(formChildCountInput.dataset.min); 1496 } 1497 } 1498 } else { 1499 if (!parseInt(formAdultCountInput.value)) { 1500 formAdultCount.classList.add("error"); 1501 hasErrors = true; 1502 } else { 1503 data.counts.adult = Object.create(null); 1504 data.counts.adult.qty = parseInt(formAdultCountInput.value); 1505 data.counts.adult.id = formAdultCountInput.dataset.id; 1506 data.counts.adult.price = parseInt(formAdultCountInput.dataset.price); 1507 data.counts.adult.min = parseInt(formAdultCountInput.dataset.min); 1508 } 1509 } 1510 1511 // check service 1512 let formServiceInput = form.querySelector(".js-order-form-service"); 1513 if (formServiceInput && formServiceInput.checked) { 1514 data.counts.service = Object.create(null); 1515 data.counts.service.qty = 1; 1516 data.counts.service.id = formServiceInput.dataset.id; 1517 } 1518 1519 // check payment 1520 let formPaymentInput = form.querySelectorAll(".js-order-form-payment"); 1521 data.onlinePayment = false; 1522 if (formPaymentInput.length) { 1523 formPaymentInput.forEach(function (input) { 1524 if (input.checked) { 1525 data.onlinePayment = input.value === 'online' ? true : false 1526 } 1527 }) 1528 } 1529 1530 // check date 1531 let formDate = form.querySelector(".order-form__datetime-item[data-type='date']"); 1532 let formDateInput = form.querySelector(".js-order-form-date"); 1533 if (!formDateInput.value) { 1534 formDate.classList.add("error"); 1535 hasErrors = true; 1536 } else { 1537 data.date = formDateInput.value; 1538 } 1539 1540 // check time 1541 let formTime = form.querySelector(".order-form__datetime-item[data-type='time']"); 1542 let formTimeInput = form.querySelector(".js-order-form-time-input"); 1543 if (!formTimeInput.value) { 1544 formTime.classList.add("error"); 1545 hasErrors = true; 1546 } else { 1547 data.time = formTimeInput.value; 1548 } 1549 1550 // check name 1551 let formName = form.querySelector("INPUT[name='name']"); 1552 if (!formName.value) { 1553 formName.classList.add("error"); 1554 hasErrors = true; 1555 } else { 1556 data.name = formName.value; 1557 } 1558 1559 // check email 1560 let formEmail = form.querySelector("INPUT[name='email']"); 1561 if (formEmail.value) { 1562 let validEmail = "[a-zа-Ñ0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zа-Ñ0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-zа-Ñ0-9](?:[a-zа-Ñ0-9-]*[a-zа-Ñ0-9])?\.)+[a-zа-Ñ0-9](?:[a-zа-Ñ0-9-]*[a-zа-Ñ0-9])?"; 1563 let emailValid = formEmail.value.match(validEmail); 1564 if (!emailValid) { 1565 formEmail.classList.add("error"); 1566 hasErrors = true; 1567 } else { 1568 data.email = formEmail.value; 1569 } 1570 } else { 1571 formEmail.classList.add("error"); 1572 hasErrors = true; 1573 } 1574 1575 // check phone 1576 let formPhone = form.querySelector("INPUT[name='phone']"); 1577 if (formPhone.value) { 1578 if (formPhone.inputmask && formPhone.inputmask.unmaskedvalue() && !formPhone.inputmask.isComplete()) { 1579 formPhone.classList.add('error'); 1580 hasErrors = true; 1581 } else { 1582 data.phone = formPhone.value; 1583 } 1584 } else { 1585 formPhone.classList.add("error"); 1586 hasErrors = true; 1587 } 1588 1589 if (hasErrors) { 1590 return; 1591 } 1592 1593 // send request 1594 form.closest('.order-form').classList.add('order-form--loading');
1595 let request = BX.ajax.runComponentAction('dl:fast.order', 'load', { 1596 mode: 'class', 1597 json: data 1598 }); 1599 1600 request.then(function (response) { 1601 form.closest('.order-form').classList.remove('order-form--loading'); 1602 if (response.status == "success") { 1603 if (response.data.result == "ok") { 1604 form.closest('.order-form').querySelector(".js-order-form-success-date").innerText = response.data.date; 1605 form.closest('.order-form').querySelector(".js-order-form-success-time").innerText = response.data.time; 1606 form.closest('.order-form').querySelector(".js-order-form-success-id").innerText = response.data.order_id; 1607 if (typeof response.data.pay_html != 'undefined' && response.data.pay_html != "") { 1608 form.closest('.order-form').querySelector(".js-order-form-success-payment").classList.add('order-form__success-payment--active'); 1609 form.closest('.order-form').querySelector(".js-order-form-success-payment").innerHTML = response.data.pay_html; 1610 let formAmount = form.closest('.order-form').querySelector(".js-order-form-success-amount"); 1611 if (formAmount) { 1612 formAmount.closest("P").style.display = "none"; 1613 } 1614 } else { 1615 let formAmount = form.closest('.order-form').querySelector(".js-order-form-success-amount"); 1616 if (formAmount && typeof response.data.amount != 'undefined') { 1617 formAmount.innerText = response.data.amount; 1618 } 1619 } 1620 form.closest('.order-form').classList.add('order-form--success'); 1621 } else { 1622 console.log('error', response); 1623 } 1624 } else { 1625 console.log('error', response); 1626 } 1627 }, function (response) { 1628 form.closest('.order-form').classList.remove('order-form--loading'); 1629 console.log('error', response); 1630 }); 1631 1632 return false; 1633 }, 1634 openPopup: function () { 1635 this.wrapper.classList.add('order-form--open'); 1636 utility.disableScroll(); 1637 }, 1638 popupClose: function () { 1639 this.wrapper.classList.remove('order-form--open'); 1640 this.wrapper.classList.remove('order-form--success'); 1641 utility.enableScroll(); 1642 }, 1643 clickPopupWrapperHandler: function (event) { 1644 if (event.target == this.popupWrapper) { 1645 this.popupClose(); 1646 } 1647 } 1648 } 1649 1650 let orderFormElement = document.querySelector('.js-order-form'); 1651 if (orderFormElement) { 1652 orderForm.init(); 1653 } 1654 1655 1656 /* fslightbox */ 1657 let photoGalleryItems = [].slice.call(document.querySelectorAll('.js-photo-gallery-item')); 1658 if (photoGalleryItems.length) { 1659 let lightbox = new FsLightbox(); 1660 1661 lightbox.props.type = 'image'; 1662 lightbox.props.showThumbsOnMount = true; 1663 lightbox.props.UIFadeOutTime = 30000; 1664 1665 lightbox.props.toolbarButtons.thumbs.title = "ÐÑкизÑ"; 1666 lightbox.props.toolbarButtons.zoomIn.title = "УвелиÑиÑÑ"; 1667 lightbox.props.toolbarButtons.zoomOut.title = "УменÑÑиÑÑ"; 1668 lightbox.props.toolbarButtons.slideshow.start.title = "ÐклÑÑиÑÑ Ð²Ð¾ÑпÑоизведение"; 1669 lightbox.props.toolbarButtons.slideshow.pause.title = "ÐÑÑановиÑÑ Ð²Ð¾ÑпÑоизведение"; 1670 lightbox.props.toolbarButtons.fullscreen.enter.title = "РазвеÑнÑÑÑ"; 1671 lightbox.props.toolbarButtons.fullscreen.exit.title = "СвеÑнÑÑÑ"; 1672 lightbox.props.toolbarButtons.close.title = "ÐакÑÑÑÑ"; 1673 lightbox.props.slideButtons.previous = { 1674 width: "16px", 1675 height: "32px", 1676 viewBox: "0 0 16 32", 1677 d: "M12.8493 30.4721C13.1409 30.9411 12.997 31.5577 12.5279 31.8493C12.0589 32.1409 11.4423 31.997 11.1507 31.5279L12.8493 30.4721ZM2.67567 16L1.82639 16.5279L1.49821 16L1.82639 15.4721L2.67567 16ZM11.1507 0.472065C11.4423 0.00301931 12.0589 -0.140856 12.5279 0.150715C12.997 0.442286 13.1409 1.05889 12.8493 1.52794L11.1507 0.472065ZM11.1507 31.5279L1.82639 16.5279L3.52496 15.4721L12.8493 30.4721L11.1507 31.5279ZM1.82639 15.4721L11.1507 0.472065L12.8493 1.52794L3.52496 16.5279L1.82639 15.4721Z", 1678 title: "ÐÑедÑдÑÑаÑ" 1679 }; 1680 lightbox.props.slideButtons.next = { 1681 width: "16px", 1682 height: "32px", 1683 viewBox: "0 0 16 32", 1684 d: "M2.15071 30.4721C1.85914 30.9411 2.00302 31.5577 2.47207 31.8493C2.94111 32.1409 3.55772 31.997 3.84929 31.5279L2.15071 30.4721ZM12.3243 16L13.1736 16.5279L13.5018 16L13.1736 15.4721L12.3243 16ZM3.84928 0.472065C3.55771 0.00301931 2.94111 -0.140856 2.47206 0.150715C2.00302 0.442286 1.85914 1.05889 2.15071 1.52794L3.84928 0.472065ZM3.84929 31.5279L13.1736 16.5279L11.475 15.4721L2.15071 30.4721L3.84929 31.5279ZM13.1736 15.4721L3.84928 0.472065L2.15071 1.52794L11.475 16.5279L13.1736 15.4721Z", 1685 title: "СледÑÑÑаÑ" 1686 }; 1687 1688 lightbox.props.sources = jsPhotoGallerySources; 1689 lightbox.props.thumbs = jsPhotoGalleryThumbs; 1690 /* lightbox.props.captions = jsPhotoGalleryCaptions; */ 1691
1692 photoGalleryItems.forEach(function (photoGalleryItem) { 1693 let index = parseInt(photoGalleryItem.dataset.index); 1694 photoGalleryItem.addEventListener('click', function () { 1695 lightbox.open(index); 1696 }); 1697 }); 1698 1699 let orderWrapper = document.querySelector('.js-order-form-popup-wrapper'); 1700 let galleryWrapper = document.querySelector('.section--photo-gallery .photo-gallery'); 1701 if (orderWrapper && galleryWrapper) { 1702 1703 window.addEventListener('load', function () { 1704 moveGallery(galleryWrapper, orderWrapper); 1705 }); 1706 1707 window.addEventListener('resize', utility.debounce(function () { 1708 moveGallery(galleryWrapper, orderWrapper); 1709 }, 250)); 1710 } 1711 } 1712 1713 function moveGallery (galleryWrapper, orderWrapper) { 1714 let targetImages = galleryWrapper.querySelector('.photo-gallery__images'); 1715 if (!targetImages) { 1716 return; 1717 } 1718 1719 let targetWrapper = orderWrapper.closest('.section.section--master-class'); 1720 if (!targetWrapper) { 1721 return; 1722 } 1723 1724 let targetImagesColumns = [].slice.call(galleryWrapper.querySelectorAll('.photo-gallery__column')); 1725 let maxWidth = 0; 1726 let columnWidth = Object.create(null); 1727 let columnIndex = 0; 1728 targetImagesColumns.forEach(function (targetImagesColumn) { 1729 let targetImagesColumnChildren = [].slice.call(targetImagesColumn.querySelectorAll('.photo-gallery__item')); 1730 columnWidth[columnIndex] = 0; 1731 targetImagesColumnChildren.forEach(function (targetImagesColumnChild) { 1732 columnWidth[columnIndex] += targetImagesColumnChild.clientWidth + 10; 1733 }); 1734 if (columnWidth[columnIndex] > maxWidth) { 1735 maxWidth = columnWidth[columnIndex]; 1736 } 1737 columnIndex++; 1738 }); 1739 1740 if (window.innerWidth > 800) { 1741 let orderWrapperPosition = orderWrapper.getBoundingClientRect(); 1742 let galleryWrapperPosition = galleryWrapper.getBoundingClientRect(); 1743 if (orderWrapperPosition.bottom < galleryWrapperPosition.top) { 1744 if (window.innerWidth > (maxWidth + 40)) { 1745 gsap.set(targetImages, { x: window.innerWidth - galleryWrapperPosition.right - (window.innerWidth - maxWidth + 20) / 2 }); 1746 let columnIndex = 0; 1747 targetImagesColumns.forEach(function (targetImagesColumn) { 1748 if (columnWidth[columnIndex] < maxWidth) { 1749 gsap.set(targetImagesColumn, { x: (columnWidth[columnIndex] - maxWidth) / 2 }); 1750 } 1751 columnIndex++; 1752 }); 1753 } else { 1754 gsap.set(targetImages, { x: window.innerWidth - galleryWrapperPosition.right }); 1755 targetImagesColumns.forEach(function (targetImagesColumn) { 1756 gsap.set(targetImagesColumn, { x: 0 }); 1757 }); 1758 } 1759 targetWrapper.style.overflow = "hidden"; 1760 } else { 1761 gsap.set(targetImages, { x: 0 }); 1762 targetImagesColumns.forEach(function (targetImagesColumn) { 1763 gsap.set(targetImagesColumn, { x: 0 }); 1764 }); 1765 targetWrapper.style.overflow = ""; 1766 } 1767 } else { 1768 gsap.set(targetImages, { x: 0 }); 1769 targetImagesColumns.forEach(function (targetImagesColumn) { 1770 gsap.set(targetImagesColumn, { x: 0 }); 1771 }); 1772 targetWrapper.style.overflow = ""; 1773 } 1774 } 1775 1776 /* chronology__content--page_nav arrow */ 1777 let ÑhronologyNavContent = document.querySelector('.section--Ñhronology .chronology__content--page_nav'); 1778 let ÑhronologySpoilerTrigger = document.querySelector('.section--Ñhronology .chronology__content--page_nav__arrow'); 1779 1780 if (ÑhronologySpoilerTrigger) { 1781 ÑhronologySpoilerTrigger.addEventListener('click', ÑhronologySpoilerClickHandler); 1782 } 1783 1784 function ÑhronologySpoilerClickHandler () { 1785 ÑhronologyNavContent.classList.toggle('show'); 1786 ÑhronologySpoilerTrigger.classList.toggle('active'); 1787 }; 1788 1789 1790 /* gridify */ 1791 window.onload = function () { 1792 gridify.init(); 1793 }; 1794 1795 window.addEventListener('resize', utility.debounce(function () { 1796 gridify.reInit(); 1797 }, 250)); 1798 1799 1800 /* worship */ 1801 let worship = document.querySelector('.js-worship'); 1802 if (worship) { 1803 let worshipItems = [].slice.call(document.querySelectorAll('.js-worship-item')); 1804 worshipItems.forEach(function (worshipItem) { 1805 let itemSaints = worshipItem.querySelector('.js-worship-saints'); 1806 if (itemSaints && itemSaints.clientHeight > 60) { 1807 itemSaints.classList.add('worship__item-saints--with-spoiler'); 1808 } 1809 1810 worshipItem.addEventListener('touchend', function (event) { 1811 if (event.target.classList.contains('js-worship-link')) { 1812 return true; 1813 } 1814 1815 if (event.target.classList.contains('js-worship-saints') && event.target.classList.contains('worship__item-saints--with-spoiler')) { 1816 event.preventDefault(); 1817 1818 let worshipSaints = event.target; 1819 if (worshipSaints.classList.contains('worship__item-saints--active')) { 1820 worshipSaints.classList.remove('worship__item-saints--active'); 1821 } else { 1822 worshipSaints.classList.add('worship__item-saints--active'); 1823 } 1824 } 1825 1826 return false; 1827 }); 1828 1829 worshipItem.addEventListener('click', function (event) { 1830 if (event.target.classList.contains('js-worship-link')) { 1831 return true; 1832 } 1833 1834 if (event.target.classList.contains('js-worship-saints') && event.target.classList.contains('worship__item-saints--with-spoiler')) { 1835 let worshipSaints = event.target; 1836 if (worshipSaints.classList.contains('worship__item-saints--active')) { 1837 worshipSaints.classList.remove('worship__item-saints--active'); 1838 } else { 1839 worshipSaints.classList.add('worship__item-saints--active'); 1840 } 1841 } 1842 1843 return false; 1844 }); 1845 }); 1846 1847 let worshipCalendarButton = document.querySelector('.js-worship-calendar-button'); 1848 let worshipCalendarWrapper = document.querySelector('.js-worship-calendar-wrapper'); 1849 if (worshipCalendarButton && worshipCalendarWrapper) { 1850 worshipCalendarButton.addEventListener('touchend', function (event) { 1851 event.stopPropagation(); 1852 event.preventDefault(); 1853
1854 showMobileCalendar(); 1855 1856 return false; 1857 }); 1858 1859 worshipCalendarButton.addEventListener('click', function (event) { 1860 event.preventDefault(); 1861 1862 showMobileCalendar(); 1863 1864 return false; 1865 }); 1866 } 1867 1868 let worshipCalendarClosers = [].slice.call(document.querySelectorAll('.js-worship-calendar-closer')); 1869 worshipCalendarClosers.forEach(function (worshipCalendarCloser) { 1870 worshipCalendarCloser.addEventListener('touchend', function (event) { 1871 event.stopPropagation(); 1872 event.preventDefault(); 1873 1874 hideMobileCalendar(); 1875 1876 return false; 1877 }); 1878 1879 worshipCalendarCloser.addEventListener('click', function (event) { 1880 event.preventDefault(); 1881 1882 hideMobileCalendar(); 1883 1884 return false; 1885 }); 1886 }); 1887 1888 let showMobileCalendar = function () { 1889 worshipCalendarWrapper.classList.add('worship__calendar-wrapper--active'); 1890 utility.disableScroll(); 1891 }; 1892 let hideMobileCalendar = function () { 1893 worshipCalendarWrapper.classList.remove('worship__calendar-wrapper--active'); 1894 utility.enableScroll(); 1895 }; 1896 1897 let worshipElementsWrapper = document.querySelector('.js-worship-elements'); 1898 if (worshipElementsWrapper && worshipCalendarButton) { 1899 let worshipObserverOptions = { 1900 rootMargin: '0px', 1901 threshold: 0.1 1902 } 1903 let worshipObserverCallback = function (entries, observer) { 1904 entries.forEach(function (entry) { 1905 if (entry.isIntersecting) { 1906 worshipCalendarButton.classList.add('worship__calendar-button--visible'); 1907 } else { 1908 worshipCalendarButton.classList.remove('worship__calendar-button--visible'); 1909 } 1910 }); 1911 }; 1912 let worshipObserver = new IntersectionObserver(worshipObserverCallback, worshipObserverOptions); 1913 worshipObserver.observe(worshipElementsWrapper); 1914 } 1915 1916 let correctWorshipCalendarCells = function () { 1917 let worshipCalendarCells = [].slice.call(worship.querySelectorAll('.qs-square')); 1918 worshipCalendarCells.forEach(function (worshipCalendarCell) { 1919 if (!worshipCalendarCell.classList.contains('qs-num--hidden') && !worshipCalendarCell.classList.contains('qs-outside-current-month')) { 1920 worshipCalendarCell.style.height = worshipCalendarCell.clientWidth + "px"; 1921 } 1922 }); 1923 }; 1924 1925 let worshipMonthsWrapper = worship.querySelector('.js-worship-months'); 1926 let currentDate = null; 1927 if (worshipMonthsWrapper) { 1928 currentDate = worshipMonthsWrapper.dataset.current; 1929 } 1930 1931 let worshipMonths = [].slice.call(worship.querySelectorAll('.js-worship-month')); 1932 worshipMonths.forEach(function (worshipMonth) { 1933 let disabledDates = []; 1934 worshipCalendarDates[worshipMonth.dataset.month].forEach(function (day) { 1935 if (!day.active) { 1936 disabledDates.push(new Date(day.value)); 1937 } 1938 }); 1939 1940 let highlightedDates = []; 1941 worshipCalendarDates[worshipMonth.dataset.month].forEach(function (day) { 1942 if (day.highlight) { 1943 highlightedDates.push(new Date(day.value)); 1944 } 1945 }); 1946 1947 let startDayElement = worshipCalendarDates[worshipMonth.dataset.month].shift(); 1948 let startDay = new Date(startDayElement.value); 1949 worshipCalendarDates[worshipMonth.dataset.month].unshift(startDayElement); 1950 1951 let endDayElement = worshipCalendarDates[worshipMonth.dataset.month].pop(); 1952 let endDay = new Date(endDayElement.value); 1953 worshipCalendarDates[worshipMonth.dataset.month].push(endDayElement); 1954 1955 let monthPicker = datepicker(worshipMonth, { 1956 formatter: function (input, date, instance) { 1957 const value = date.toLocaleDateString('ru-RU'); 1958 input.value = value; 1959 }, 1960 onSelect: function (instance, date) { 1961 const value = date.toLocaleDateString('ru-RU'); 1962 let valueParts; 1963 let url; 1964 1965 if (value.includes("/")) { 1966 valueParts = value.split("/"); 1967 url = "/worship/date-" + valueParts[2] + "-" + valueParts[0] + "-" + valueParts[1] + "/"; 1968 } else { 1969 valueParts = value.split("."); 1970 url = "/worship/date-" + valueParts[0] + "-" + valueParts[1] + "-" + valueParts[2] + "/"; 1971 } 1972 1973 window.location.href = url; 1974 }, 1975 onMonthChange: function (instance) { 1976 let target = instance.calendar; 1977 let days = [].slice.call(target.querySelectorAll('.qs-num'));
1978 let calendarDate = instance.el.dataset.date; 1979 let calendarMonth = instance.el.dataset.month; 1980 let calendarActiveDates = []; 1981 worshipCalendarDates[calendarMonth].forEach(function (day) { 1982 calendarActiveDates.push(day.value.replaceAll('-', '.')); 1983 }); 1984 days.forEach(function (day) { 1985 let currentDay = day.innerHTML; 1986 while (currentDay.length < 2) currentDay = "0" + currentDay; 1987 let calendarDateValues = calendarDate.split("."); 1988 currentDay = calendarDateValues[0] + "." + calendarDateValues[1] + "." + currentDay; 1989 if (!calendarActiveDates.includes(currentDay)) { 1990 day.classList.add('qs-num--hidden'); 1991 } 1992 if (!day.classList.contains('qs-disabled')) { 1993 if (!day.previousSibling || (day.previousSibling && !day.previousSibling.classList.contains('qs-num')) || (day.previousSibling && day.previousSibling.classList.contains('qs-disabled'))) { 1994 day.classList.add('qs-num--first'); 1995 } 1996 if (!day.nextSibling || (day.nextSibling && !day.nextSibling.classList.contains('qs-num')) || (day.nextSibling && day.nextSibling.classList.contains('qs-disabled'))) { 1997 day.classList.add('qs-num--last'); 1998 } 1999 } 2000 }); 2001 correctWorshipCalendarCells(); 2002 }, 2003 position: "bl", 2004 startDay: 1, 2005 defaultView: "calendar", 2006 alwaysShow: false, 2007 minDate: startDay, 2008 maxDate: endDay, 2009 showAllDates: false, 2010 disabledDates: disabledDates, 2011 events: highlightedDates, 2012 disableMobile: false, 2013 disableYearOverlay: true 2014 }); 2015 if (worshipMonth.value) { 2016 let value = worshipMonth.value; 2017 let valueParts; 2018 let date; 2019 2020 if (value.includes("/")) { 2021 valueParts = value.split("/"); 2022 date = new Date(Number(valueParts[2]), Number(valueParts[0]) - 1, Number(valueParts[1])); 2023 } else { 2024 valueParts = value.split("."); 2025 if (valueParts[0].length === 4) { 2026 date = new Date(Number(valueParts[0]), Number(valueParts[1]) - 1, Number(valueParts[2])); 2027 } else { 2028 date = new Date(Number(valueParts[2]), Number(valueParts[1]) - 1, Number(valueParts[0])); 2029 } 2030 } 2031 2032 monthPicker.setDate(date); 2033 } 2034 monthPicker.show(); 2035 monthPicker.navigate(endDay, true); 2036 }); 2037 window.addEventListener('resize', utility.throttle(function () { 2038 correctWorshipCalendarCells(); 2039 }, 100)); 2040 correctWorshipCalendarCells(); 2041 2042 /* correct js-worship-link width */ 2043 let worshipLinks = [...document.querySelectorAll('.js-worship-link')]; 2044 2045 let worshipDateLinks = []; 2046 worshipLinks.forEach(worshipLink => { 2047 if (worshipLink.classList.contains('worship__item-date') && !worshipLink.closest('.worship__item--active')) { 2048 worshipDateLinks.push(worshipLink); 2049 } 2050 }); 2051 2052 let worshipDateLinkWidths = []; 2053 worshipDateLinks.forEach(worshipDateLink => { 2054 worshipDateLinkWidths.push(worshipDateLink.getBoundingClientRect().width); 2055 }); 2056 2057 let worshipDateLinkMaxWidth = Math.ceil(Math.max.apply(null, worshipDateLinkWidths)); 2058 worshipDateLinks.forEach(worshipDateLink => { 2059 worshipDateLink.style.width = worshipDateLinkMaxWidth + "px"; 2060 }); 2061 } 2062 2063 2064 /* news calendar */ 2065 let chronologySelectDay = document.querySelector('.js-chrono-select-day'); 2066 let newsCalendar = document.querySelector('.js-news-calendar'); 2067 let newsCalendarClosers = [].slice.call(document.querySelectorAll('.js-news-calendar-closer')); 2068 if (chronologySelectDay && newsCalendar) { 2069 chronologySelectDay.addEventListener('touchend', chronologySelectDayTouchHandler); 2070 chronologySelectDay.addEventListener('click', chronologySelectDayClickHandler); 2071 newsCalendarClosers.forEach(function (newsCalendarCloser) { 2072 newsCalendarCloser.addEventListener('touchend', chronologyCloserTouchHandler); 2073 newsCalendarCloser.addEventListener('click', chronologyCloserClickHandler); 2074 }); 2075 2076 let newsCalendarInput = document.querySelector('.js-news-calendar-input'); 2077 if (newsCalendarInput) { 2078 let enableDates = []; 2079 for (item in newsCalendarDates) { 2080 enableDates.push(newsCalendarDates[item]); 2081 } 2082 2083 let newsCalendarPicker = datepicker(newsCalendarInput, { 2084 formatter: function (input, date, instance) { 2085 const value = date.toLocaleDateString('ru-RU'); 2086 input.value = value; 2087 }, 2088 onSelect: function (instance, date) { 2089 const value = date.toLocaleDateString('ru-RU'); 2090 let valueParts; 2091 let url; 2092 2093 if (value.includes("/")) { 2094 valueParts = value.split("/"); 2095 url = "/lavra-news/date-" + valueParts[2] + "-" + valueParts[0] + "-" + valueParts[1] + "/"; 2096 } else { 2097 valueParts = value.split("."); 2098 url = "/lavra-news/date-" + valueParts[0] + "-" + valueParts[1] + "-" + valueParts[2] + "/"; 2099 } 2100 2101 window.location.href = url; 2102 }, 2103 onMonthChange: function (instance) { 2104 initNewsCalendar(instance); 2105 }, 2106 onShow: function (instance) { 2107 initNewsCalendar(instance); 2108 }, 2109 disabler: function (date) { 2110 const value = date.toLocaleDateString('ru-RU'); 2111 let values = value.split("."); 2112 let dateValue = values[2] + "-" + values[1] + "-" + values[0];
2113 return !enableDates.includes(dateValue); 2114 }, 2115 position: "bl", 2116 startDay: 1, 2117 defaultView: "calendar", 2118 alwaysShow: true, 2119 showAllDates: false, 2120 disableMobile: false, 2121 disableYearOverlay: false, 2122 customDays: ['ÐÑ', 'Ðн', 'ÐÑ', 'СÑ', 'ЧÑ', 'ÐÑ', 'Сб'], 2123 customMonths: ['ЯнваÑÑ', 'ФевÑалÑ', 'ÐаÑÑ', 'ÐпÑелÑ', 'Ðай', 'ÐÑнÑ', 'ÐÑлÑ', 'ÐвгÑÑÑ', 'СенÑÑбÑÑ', 'ÐкÑÑбÑÑ', 'ÐоÑбÑÑ', 'ÐекабÑÑ'], 2124 overlayButton: "ÐÑбÑаÑÑ", 2125 overlayPlaceholder: "УкажиÑе год (4 ÑиÑÑÑ)" 2126 }); 2127 2128 if (newsCalendarInput.value) { 2129 let value = newsCalendarInput.value; 2130 let valueParts; 2131 let date; 2132 2133 if (value.includes("/")) { 2134 valueParts = value.split("/"); 2135 date = new Date(Number(valueParts[2]), Number(valueParts[0]) - 1, Number(valueParts[1])); 2136 } else { 2137 valueParts = value.split("."); 2138 if (valueParts[0].length === 4) { 2139 date = new Date(Number(valueParts[0]), Number(valueParts[1]) - 1, Number(valueParts[2])); 2140 } else { 2141 date = new Date(Number(valueParts[2]), Number(valueParts[1]) - 1, Number(valueParts[0])); 2142 } 2143 } 2144 2145 newsCalendarPicker.setDate(date); 2146 newsCalendarPicker.navigate(date, true); 2147 } else { 2148 newsCalendarPicker.show(); 2149 } 2150 } 2151 } 2152 2153 function chronologySelectDayTouchHandler (event) { 2154 event.stopPropagation(); 2155 event.preventDefault(); 2156 2157 if (newsCalendar.classList.contains('news-calendar--active')) { 2158 chronologyHideCalendar(); 2159 } else { 2160 chronologyShowCalendar(); 2161 } 2162 2163 return false; 2164 } 2165 2166 function chronologySelectDayClickHandler (event) { 2167 event.preventDefault(); 2168 2169 if (newsCalendar.classList.contains('news-calendar--active')) { 2170 chronologyHideCalendar(); 2171 } else { 2172 chronologyShowCalendar(); 2173 } 2174 2175 return false; 2176 } 2177 2178 function chronologyCloserTouchHandler (event) { 2179 event.stopPropagation(); 2180 event.preventDefault(); 2181 2182 chronologyHideCalendar(); 2183 2184 return false; 2185 } 2186 2187 function chronologyCloserClickHandler (event) { 2188 event.preventDefault(); 2189 2190 chronologyHideCalendar(); 2191 2192 return false; 2193 } 2194 2195 function chronologyShowCalendar () { 2196 newsCalendar.classList.add('news-calendar--active'); 2197 utility.disableScroll(); 2198 } 2199 2200 function chronologyHideCalendar () { 2201 newsCalendar.classList.remove('news-calendar--active'); 2202 utility.enableScroll(); 2203 } 2204 2205 function initNewsCalendar (instance) { 2206 let target = instance.calendar; 2207 let days = [].slice.call(target.querySelectorAll('.qs-num')); 2208 days.forEach(function (day) { 2209 if (!day.classList.contains('qs-disabled')) { 2210 if (!day.previousSibling || (day.previousSibling && !day.previousSibling.classList.contains('qs-num')) || (day.previousSibling && day.previousSibling.classList.contains('qs-disabled'))) { 2211 day.classList.add('qs-num--first'); 2212 } 2213 if (!day.nextSibling || (day.nextSibling && !day.nextSibling.classList.contains('qs-num')) || (day.nextSibling && day.nextSibling.classList.contains('qs-disabled'))) { 2214 day.classList.add('qs-num--last'); 2215 } 2216 } 2217 }); 2218 2219 correctNewsCalendarCells(instance); 2220 } 2221 2222 function correctNewsCalendarCells (instance) { 2223 let target = instance.calendar; 2224 let days = [].slice.call(target.querySelectorAll('.qs-num')); 2225 2226 days.forEach(function (day) { 2227 let rect = day.getBoundingClientRect(); 2228 day.style.height = rect.width + "px"; 2229 }); 2230 }; 2231 2232 2233 if (document.getElementById('inline-picker')) { 2234 const picker = datepicker('#inline-picker', { 2235 customDays: ['Ðн', 'ÐÑ', 'СÑ', 'ЧÑ', 'ÐÑ', 'Сб', 'ÐÑ'], 2236 customMonths: ['ЯнваÑÑ', 'ФевÑалÑ', 'ÐаÑÑ', 'ÐпÑелÑ', 'Ðай', 'ÐÑнÑ', 'ÐÑлÑ', 'ÐвгÑÑÑ', 'СенÑÑбÑÑ', 'ÐкÑÑбÑÑ', 'ÐоÑбÑÑ', 'ÐекабÑÑ'], 2237 defaultView: "calendar", 2238 overlayButton: "ÐÑбÑаÑÑ", 2239 overlayPlaceholder: "УкажиÑе год (4 ÑиÑÑÑ)", 2240 alwaysShow: true, 2241 }) 2242 } 2243 2244 2245 let calendarPopUp = document.getElementById('calendar-popup') 2246 if (calendarPopUp) { 2247 let calendarPopupOpen = document.querySelectorAll('.calendar-popup__open') 2248 let calendarPopupClose = document.querySelectorAll('.calendar-popup__close') 2249
2250 calendarPopupOpen.forEach(el => el.addEventListener('click', function () { 2251 calendarPopUp.classList.add('active') 2252 })) 2253 2254 calendarPopupClose.forEach(el => el.addEventListener('click', function () { 2255 el.closest('.calendar-popup').classList.remove('active') 2256 })) 2257 2258 calendarPopUp.addEventListener('mouseup', function (e) { 2259 if (!e.target.closest('.calendar-popup__wrap')) { 2260 this.closest('.calendar-popup').classList.remove('active') 2261 } 2262 }) 2263 } 2264 2265 /* chronology photo grid */ 2266 (() => { 2267 console.log('-1-') 2268 window.addEventListener('DOMContentLoaded', () => { 2269 console.log('-2-') 2270 const galleryRows = [...document.querySelectorAll('.js-chrono-photo-row')]; 2271 const showMoreButton = document.getElementById('loadmore'); 2272 const contentWrapper = document.querySelector('.news-page__detail__left'); 2273 const pageWrapper = document.querySelector('.js-photo-gallery-wrapper'); 2274 const relatedWrapper = document.querySelector('.section--photo-gallery.section--photo-gallery--albumPage'); 2275 2276 window.addEventListener('resize', utility.debounce(function () { 2277 gallerySetSizes(); 2278 if (relatedWrapper && contentWrapper && pageWrapper) { 2279 moveGalleryRelated(); 2280 } 2281 }, 250)); 2282 gallerySetSizes(); 2283 if (relatedWrapper && contentWrapper && pageWrapper) { 2284 moveGalleryRelated(); 2285 } 2286 2287 if (showMoreButton) { 2288 showMoreButton.addEventListener('click', galleryShowMore); 2289 } 2290 2291 function gallerySetSizes () { 2292 galleryRows.forEach(function (galleryRow) { 2293 if (galleryRow.closest('.photo-gallery__row').dataset.visible === 'false') { 2294 return; 2295 } 2296 let galleryRowRatios = []; 2297 let galleryRowMaxHeight = null; 2298 let galleryRowWidth = 0; 2299 let galleryImages = [...galleryRow.querySelectorAll('.js-chrono-photo-image')]; 2300 2301 if (galleryRow.closest('.photo-gallery__row')) { 2302 galleryRowWidth = galleryRow.closest('.photo-gallery__row').clientWidth - (10 * (galleryImages.length - 1)); 2303 } 2304 2305 let rowIndex = Number(galleryRow.closest('.photo-gallery__row').dataset.row); 2306 if (rowIndex == galleryRows.length) { 2307 let rowLimit = Number(galleryRow.dataset.limit); 2308 if (galleryImages.length < rowLimit) { 2309 for (let i = 0; i < rowLimit - galleryImages.length; i++) { 2310 let placeholder = document.createElement('div'); 2311 let placeholderInner = document.createElement('div'); 2312 let placeholderImage = document.createElement('div'); 2313 2314 placeholder.className = "photo-gallery__item"; 2315 placeholderInner.className = "photo-gallery__item-link"; 2316 placeholderImage.classList.add("photo-item--placeholder", "js-chrono-photo-image"); 2317 2318 placeholderInner.appendChild(placeholderImage); 2319 placeholder.appendChild(placeholderInner); 2320 galleryRow.appendChild(placeholder); 2321 } 2322 } 2323 } 2324 2325 galleryImages = [...galleryRow.querySelectorAll('.js-chrono-photo-image')]; 2326 2327 let imageRatio; 2328 galleryImages.forEach(function (galleryImage) { 2329 if (!galleryImage.classList.contains('photo-item--placeholder')) { 2330 imageRatio = parseInt(galleryImage.getAttribute('width')) / parseInt(galleryImage.getAttribute('height')); 2331 } 2332 2333 galleryRowRatios.push(imageRatio); 2334 if (galleryRowMaxHeight == null || parseInt(galleryImage.getAttribute('height')) < galleryRowMaxHeight) { 2335 galleryRowMaxHeight = parseInt(galleryImage.getAttribute('height')); 2336 } 2337 }); 2338 2339 let targetHeight = galleryRowMaxHeight; 2340 let testWidth = checkRowWidth(galleryRowRatios, targetHeight); 2341 if (testWidth >= galleryRowWidth) { 2342 while (checkRowWidth(galleryRowRatios, targetHeight) >= galleryRowWidth) { 2343 targetHeight--; 2344 } 2345 } else { 2346 while (checkRowWidth(galleryRowRatios, targetHeight) < galleryRowWidth) { 2347 targetHeight++; 2348 } 2349 } 2350 2351 let itemWidth = 0; 2352 galleryImages.forEach(function (galleryImage) { 2353 if (!galleryImage.classList.contains('photo-item--placeholder')) { 2354 let imageRatio = parseInt(galleryImage.getAttribute('width')) / parseInt(galleryImage.getAttribute('height')); 2355 galleryRowRatios.push(imageRatio); 2356 itemWidth = imageRatio * targetHeight; 2357 } 2358 galleryImage.style.setProperty('--item-width', `${itemWidth}px`); 2359 });
2360 2361 let rowHeight = targetHeight + 10; 2362 galleryRow.closest('.photo-gallery__row').style.setProperty('--row-height', `${rowHeight}px`); 2363 }); 2364 } 2365 2366 function checkRowWidth (ratios, height) { 2367 let width = 0; 2368 2369 ratios.forEach(function (ratio) { 2370 width += height * ratio; 2371 }); 2372 2373 return Math.round(width); 2374 } 2375 2376 function galleryShowMore () { 2377 let rowCount = 0; 2378 galleryRows.forEach(galleryRow => { 2379 if (galleryRow.closest('.photo-gallery__row').dataset.visible === 'true') { 2380 return; 2381 } 2382 if (++rowCount <= 14) { 2383 galleryRow.closest('.photo-gallery__row').dataset.visible = "true"; 2384 } 2385 }); 2386 2387 if (rowCount <= 14) { 2388 showMoreButton.removeEventListener('click', galleryShowMore); 2389 showMoreButton.remove(); 2390 } 2391 2392 gallerySetSizes(); 2393 } 2394 2395 function moveGalleryRelated () { 2396 if (window.innerWidth > 800) { 2397 pageWrapper.appendChild(relatedWrapper); 2398 } else { 2399 contentWrapper.appendChild(relatedWrapper); 2400 } 2401 } 2402 }); 2403 })(); 2404 2405 /* chronology main nav toggle */ 2406 (() => { 2407 window.addEventListener('DOMContentLoaded', () => { 2408 const chronologyNavToggler = document.querySelector('.js-chronology-nav-toggler'); 2409 const chronologyNav = document.querySelector('.chronology-news__links'); 2410 2411 if (chronologyNavToggler && chronologyNav) { 2412 chronologyNavToggler.addEventListener('click', event => { 2413 event.preventDefault(); 2414 2415 let togglerText = chronologyNavToggler.querySelector('.text'); 2416 let togglerIcon = chronologyNavToggler.querySelector('.icon'); 2417 2418 if (chronologyNav.classList.contains('chronology-news__links--open')) { 2419 chronologyNav.classList.remove('chronology-news__links--open'); 2420 togglerText.textContent = chronologyNavToggler.dataset.textOpen; 2421 togglerIcon.classList.remove('icon--chevron-up'); 2422 togglerIcon.classList.add('icon--chevron-down'); 2423 } else { 2424 chronologyNav.classList.add('chronology-news__links--open'); 2425 togglerText.textContent = chronologyNavToggler.dataset.textClose; 2426 togglerIcon.classList.add('icon--chevron-up'); 2427 togglerIcon.classList.remove('icon--chevron-down'); 2428 } 2429 2430 return false; 2431 }) 2432 } 2433 }); 2434 })(); 2435 2436 /* info blocks */ 2437 (() => { 2438 let infoBlocksOldWidth; 2439 let infoBlocksNewWidth; 2440 let infoBlocks; 2441 let infoBlocksItems = Object.create(null); 2442 2443 window.addEventListener('DOMContentLoaded', () => { 2444 infoBlocks = document.querySelector('.js-info-blocks'); 2445 2446 if (infoBlocks && typeof infoBlocksConfig !== 'undefined') { 2447 infoBlocksOldWidth = window.innerWidth; 2448 2449 getInfoBlocksItems();
2450 2451 window.addEventListener('resize', utility.debounce(function () { 2452 checkRenderInfoBlocks(false); 2453 }, 250)); 2454 2455 checkRenderInfoBlocks(true); 2456 } 2457 }); 2458 2459 function checkRenderInfoBlocks (force) { 2460 infoBlocksNewWidth = window.innerWidth; 2461 2462 let infoBlocksOldLayout = null; 2463 let infoBlocksNewLayout = null; 2464 2465 for (let layout in infoBlocksConfig) { 2466 if (infoBlocksOldWidth >= infoBlocksConfig[layout].dimensions.min && infoBlocksOldWidth <= infoBlocksConfig[layout].dimensions.max) { 2467 infoBlocksOldLayout = layout; 2468 } 2469 2470 if (infoBlocksNewWidth >= infoBlocksConfig[layout].dimensions.min && infoBlocksNewWidth <= infoBlocksConfig[layout].dimensions.max) { 2471 infoBlocksNewLayout = layout; 2472 } 2473 } 2474 2475 if (infoBlocksOldLayout !== infoBlocksNewLayout || force) { 2476 renderInfoBlocks(infoBlocksNewLayout); 2477 } 2478 2479 infoBlocksOldWidth = infoBlocksNewWidth; 2480 } 2481 2482 function renderInfoBlocks (layout) { 2483 infoBlocks.innerHTML = ""; 2484 2485 let columns = ['left', 'center', 'right']; 2486 for (let columnType of columns) { 2487 if (!infoBlocksConfig[layout].items.hasOwnProperty(columnType)) { 2488 continue; 2489 } 2490 2491 let column = document.createElement('div'); 2492 column.classList.add('info-blocks__column', 'info-blocks__column--' + columnType); 2493 2494 for (let itemType of infoBlocksConfig[layout].items[columnType]) { 2495 let item = infoBlocksItems[itemType].cloneNode(true); 2496 column.appendChild(item); 2497 } 2498 2499 infoBlocks.appendChild(column); 2500 } 2501 } 2502 2503 function getInfoBlocksItems () { 2504 let items = [...document.querySelectorAll('.js-info-block')]; 2505 items.map(item => { 2506 infoBlocksItems[item.dataset.type] = item; 2507 }); 2508 } 2509 })(); 2510 2511 /* home page */ 2512 (() => { 2513 const tabletWidth = 600; 2514 const desktopWidth = 1000; 2515 2516 let homepageOldWidth; 2517 let homepageNewWidth; 2518 let homepageOldLayout = 'mobile'; 2519 let homepageNewLayout; 2520 2521 let homepage = document.querySelector('HTML.page--main'); 2522 2523 if (homepage) { 2524 window.addEventListener('DOMContentLoaded', () => { 2525 homepageOldWidth = window.innerWidth; 2526 2527 window.addEventListener('resize', utility.debounce(function () { 2528 checkRenderHomepage(); 2529 }, 250)); 2530 2531 checkRenderHomepage(); 2532 }); 2533 } 2534 2535 function moveGalleryRelated () { 2536 if (window.innerWidth > 800) { 2537 pageWrapper.appendChild(relatedWrapper); 2538 } else { 2539 contentWrapper.appendChild(relatedWrapper); 2540 } 2541 } 2542 2543 function checkRenderHomepage () { 2544 homepageNewWidth = window.innerWidth; 2545 2546 homepageNewLayout = 'mobile'; 2547 if (homepageNewWidth > tabletWidth) { 2548 homepageNewLayout = 'tablet'; 2549 } 2550 if (homepageNewWidth > desktopWidth) { 2551 homepageNewLayout = 'desktop'; 2552 } 2553 2554 if (homepageOldLayout !== homepageNewLayout) { 2555 renderHomepage(homepageNewLayout); 2556 } 2557 2558 homepageOldLayout = homepageNewLayout; 2559 homepageOldWidth = homepageNewWidth; 2560 } 2561 2562 function renderHomepage (layout) { 2563 console.log('hp render') 2564 let homeHeroWrapper = document.querySelector('.js-home-hero-wrapper'); 2565 let homeNewsListWrapper = document.querySelector('.js-home-news-list-wrapper'); 2566 let homePhotoWrapper = document.querySelector('.js-home-photo-wrapper'); 2567 let homeVideoListWrapper = document.querySelector('.js-home-video-list-wrapper'); 2568 let homeBannersWrapper = document.querySelector('.js-home-banners-wrapper'); 2569 let homeMobileWrapper = document.querySelector('.js-home-mobile-wrapper'); 2570 2571 let homeItemMainNew = document.querySelector('.js-home-item-main-new'); 2572 let homeItemNewsList = document.querySelector('.js-home-item-news-list'); 2573 let homeItemPhoto = document.querySelector('.js-home-item-photo'); 2574 let homeItemShop = document.querySelector('.js-home-item-shop'); 2575 2576 switch (layout) { 2577 case "mobile": 2578 homeHeroWrapper.appendChild(homeItemMainNew); 2579 homeMobileWrapper.appendChild(homeItemNewsList); 2580 homeMobileWrapper.appendChild(homeItemPhoto); 2581 break; 2582 case "tablet": 2583 homeHeroWrapper.appendChild(homeItemMainNew); 2584 homeNewsListWrapper.appendChild(homeItemNewsList); 2585 homePhotoWrapper.appendChild(homeItemPhoto); 2586 homeBannersWrapper.appendChild(homeItemShop); 2587 break; 2588 case "desktop": 2589 homeHeroWrapper.appendChild(homeItemMainNew); 2590 homeNewsListWrapper.appendChild(homeItemNewsList); 2591 homeVideoListWrapper.appendChild(homeItemShop); 2592 homeVideoListWrapper.insertBefore(homeItemShop, homeVideoListWrapper.firstChild); 2593 homePhotoWrapper.appendChild(homeItemPhoto); 2594 break; 2595 } 2596 2597 // init custom event 2598 const homepageRenderEvent = new CustomEvent('homepage.render', { detail: layout });
2599 let mainColumns = document.querySelector(".js-home-columns"); 2600 if (mainColumns) { 2601 mainColumns.dispatchEvent(homepageRenderEvent); 2602 } 2603 } 2604 })(); 2605 2606 /* body color */ 2607 (() => { 2608 let homepageOldWidth; 2609 let homepageNewWidth; 2610 let mainColumns; 2611 2612 window.addEventListener('DOMContentLoaded', () => { 2613 mainColumns = document.querySelector(".js-home-columns"); 2614 2615 if (mainColumns) { 2616 homepageOldWidth = window.innerWidth; 2617 2618 window.addEventListener('resize', utility.debounce(function () { 2619 checkBodyColor(); 2620 }, 100)); 2621 2622 window.addEventListener('load', checkBodyColor); 2623 mainColumns.addEventListener('homepage.render', checkBodyColor); 2624 } 2625 }); 2626 2627 function checkBodyColor () { 2628 homepageNewWidth = window.innerWidth; 2629 2630 if ((homepageOldWidth <= 1000 && homepageNewWidth > 1000) || (homepageOldWidth == homepageNewWidth && homepageNewWidth > 1000)) { 2631 initBodyColor(); 2632 } else if (homepageNewWidth <= 1000 && homepageOldWidth > 1000) { 2633 clearBodyColor(); 2634 } else { 2635 if (homepageNewWidth > 1000) { 2636 clearBodyColor(); 2637 initBodyColor(); 2638 } 2639 } 2640 2641 homepageOldWidth = homepageNewWidth; 2642 } 2643 2644 function initBodyColor () { 2645 let triggerOffset = Math.max(0.4 * window.innerHeight, mainColumns.getBoundingClientRect().top + window.pageYOffset - 0.4 * window.innerHeight); 2646 ScrollTrigger.create({ 2647 id: "homepageBodyColor", 2648 toggleClass: { 2649 targets: "BODY", 2650 className: "light-bg" 2651 }, 2652 start: triggerOffset, 2653 end: 20000 2654 }); 2655 } 2656 2657 function clearBodyColor () { 2658 let triggers = ScrollTrigger.getAll(); 2659 triggers.forEach(trigger => { 2660 if (trigger.id == "clearBodyColor") { 2661 trigger.kill(); 2662 } 2663 }); 2664 } 2665 })(); 2666 2667 /* column scroll */ 2668 (() => { 2669 let homepageOldWidth; 2670 let homepageNewWidth; 2671 2672 let homepage = document.querySelector('HTML.page--main'); 2673 2674 if (homepage) { 2675 2676 let mainColumns = document.querySelector(".js-home-columns"); 2677 let targetColumn = mainColumns.querySelector(".js-home-column-1"); 2678 let photoColumn = mainColumns.querySelector(".js-home-column-2"); 2679 let bannerColumn = mainColumns.querySelector(".js-home-column-3"); 2680 let imagesColumn = mainColumns.querySelector(".js-home-column-l"); 2681 let videoColumn = mainColumns.querySelector(".js-home-column-r"); 2682 let photoColumnOffset; 2683 let bannerColumnOffset; 2684 let imagesColumnOffset; 2685 let videoColumnOffset; 2686 2687 window.addEventListener('DOMContentLoaded', () => { 2688 homepageOldWidth = window.innerWidth; 2689 2690 window.addEventListener('resize', utility.debounce(function () { 2691 checkScroll(); 2692 }, 100)); 2693 2694 window.addEventListener('load', checkScroll); 2695 2696 if (mainColumns) { 2697 mainColumns.addEventListener('homepage.render', checkScroll); 2698 } 2699 }); 2700 2701 function checkScroll () { 2702 homepageNewWidth = window.innerWidth; 2703 2704 if ((homepageOldWidth <= 1000 && homepageNewWidth > 1000) || (homepageOldWidth == homepageNewWidth && homepageNewWidth > 1000)) { 2705 initScroll(); 2706 } else if (homepageNewWidth <= 1000 && homepageOldWidth > 1000) { 2707 clearScroll(); 2708 } else { 2709 if (homepageNewWidth > 1000) { 2710 clearScroll(); 2711 initScroll(); 2712 } 2713 } 2714 2715 if (homepageNewWidth > 600 && homepageNewWidth <= 1000) { 2716 setColumnOffset(); 2717 } else { 2718 resetColumnOffset(); 2719 } 2720 2721 homepageOldWidth = homepageNewWidth; 2722 } 2723 2724 function initScroll () { 2725 if (targetColumn) { 2726 if (photoColumn) { 2727 photoColumnOffset = targetColumn.getBoundingClientRect().bottom - 50 - photoColumn.getBoundingClientRect().bottom; 2728 } 2729 if (bannerColumn) { 2730 bannerColumnOffset = targetColumn.getBoundingClientRect().bottom - 50 - bannerColumn.getBoundingClientRect().bottom; 2731 } 2732 if (imagesColumn) { 2733 imagesColumnOffset = targetColumn.getBoundingClientRect().bottom - 50 - imagesColumn.getBoundingClientRect().bottom; 2734 } 2735 if (videoColumn) { 2736 videoColumnOffset = targetColumn.getBoundingClientRect().bottom - 50 - videoColumn.getBoundingClientRect().bottom; 2737 } 2738 2739 let targetColumnHeight = targetColumn.getBoundingClientRect().height; 2740 mainColumns.style.height = targetColumnHeight + 134 + "px"; 2741 } 2742 2743 // photo column scroll 2744 if (photoColumn && photoColumnOffset) { 2745 gsap.to(photoColumn, { 2746 y: () => photoColumnOffset, 2747 ease: "none", 2748 scrollTrigger: { 2749 id: "homepagePhotoColumn", 2750 trigger: mainColumns, 2751 start: "top center", 2752 end: "bottom center", 2753 scrub: 0, 2754 invalidateOnRefresh: true 2755 } 2756 });
2757 } 2758 2759 // banner column scroll 2760 if (bannerColumn && bannerColumnOffset) { 2761 gsap.to(bannerColumn, { 2762 y: () => bannerColumnOffset, 2763 ease: "none", 2764 scrollTrigger: { 2765 id: "homepageBannerColumn", 2766 trigger: mainColumns, 2767 start: "top center", 2768 end: "bottom center", 2769 scrub: 0, 2770 invalidateOnRefresh: true 2771 } 2772 }); 2773 } 2774 2775 // images column scroll 2776 if (imagesColumn && imagesColumnOffset) { 2777 gsap.to(imagesColumn, { 2778 y: () => imagesColumnOffset, 2779 ease: "none", 2780 scrollTrigger: { 2781 id: "homepageImagesColumn", 2782 trigger: mainColumns, 2783 start: "top center", 2784 end: "bottom center", 2785 scrub: 0, 2786 invalidateOnRefresh: true 2787 } 2788 }); 2789 } 2790 2791 // video column scroll 2792 if (videoColumn && videoColumnOffset) { 2793 gsap.to(videoColumn, { 2794 y: () => videoColumnOffset, 2795 ease: "none", 2796 scrollTrigger: { 2797 id: "homepageVideoColumn", 2798 trigger: mainColumns, 2799 start: "top center", 2800 end: "bottom center", 2801 scrub: 0, 2802 invalidateOnRefresh: true 2803 } 2804 }); 2805 } 2806 } 2807 2808 function clearScroll () { 2809 mainColumns.style.height = ""; 2810 2811 let triggers = ScrollTrigger.getAll(); 2812 let targetTriggers = ["homepageVideoColumn", "homepageImagesColumn", "homepageBannerColumn", "homepagePhotoColumn"]; 2813 triggers.forEach(trigger => { 2814 if (targetTriggers.includes(trigger.id)) { 2815 trigger.kill(); 2816 } 2817 }); 2818 } 2819 2820 function setColumnOffset () { 2821 let exampleElement = document.querySelector('.js-home-item-main-new'); 2822 let targetElement = document.querySelector('.js-home-column-3'); 2823 targetElement.style.marginTop = -(exampleElement.getBoundingClientRect().height + 32) + "px"; 2824 } 2825 2826 function resetColumnOffset () { 2827 let targetElement = document.querySelector('.js-home-column-3'); 2828 targetElement.style.marginTop = ""; 2829 } 2830 } 2831 })(); 2832 2833 /* reverend hover */ 2834 (() => { 2835 let container; 2836 let containerSize; 2837 let mousePos; 2838 let shadows; 2839 2840 window.addEventListener('DOMContentLoaded', () => { 2841 container = document.querySelector('.js-reverend-hover'); 2842 2843 if (container) { 2844 shadows = [...document.querySelectorAll('.js-reverend-shadow')]; 2845 container.addEventListener('mouseleave', mouseLeaveHandler); 2846 container.addEventListener('mousemove', mouseMoveHandler); 2847 2848 window.addEventListener('resize', calcContainerSize); 2849 window.addEventListener('load', () => { 2850 calcContainerSize(); 2851 render(); 2852 }); 2853 2854 calcContainerSize(); 2855 2856 mousePos = { 2857 x: containerSize.width / 2, 2858 y: containerSize.height / 2 2859 }; 2860 } 2861 }); 2862 2863 function calcContainerSize () { 2864 containerSize = { 2865 width: container.getBoundingClientRect().width, 2866 height: container.getBoundingClientRect().height 2867 }; 2868 } 2869 2870 function getMousePos (event) { 2871 let posX = 0; 2872 let posY = 0; 2873 if (!event) { 2874 event = window.event; 2875 } 2876 if (event.pageX || event.pageY) { 2877 posX = event.pageX - container.offsetLeft; 2878 posY = event.pageY - container.offsetTop; 2879 } 2880 return { x: posX, y: posY }; 2881 } 2882 2883 function mouseLeaveHandler () { 2884 mousePos = { 2885 x: containerSize.width / 2, 2886 y: containerSize.height / 2 2887 }; 2888 } 2889 2890 function mouseMoveHandler (event) { 2891 mousePos = getMousePos(event); 2892 } 2893 2894 function render () { 2895 let mouseMoveValues = { 2896 translationX: 0, 2897 translationY: 0 2898 }; 2899 2900 const raf = () => { 2901 mouseMoveValues.translationX = utility.lerp( 2902 mouseMoveValues.translationX, 2903 utility.lineEq(-10, 10, containerSize.width, 0, mousePos.x), 2904 0.025 2905 ); 2906 mouseMoveValues.translationX = Math.round(mouseMoveValues.translationX * 1000) / 1000; 2907 mouseMoveValues.translationY = utility.lerp( 2908 mouseMoveValues.translationY, 2909 utility.lineEq(-5, 5, containerSize.height, 0, mousePos.y), 2910 0.025 2911 ); 2912 mouseMoveValues.translationY = Math.round(mouseMoveValues.translationY * 1000) / 1000; 2913 2914 shadows.forEach(shadow => { 2915 gsap.set(shadow, { 2916 x: mouseMoveValues.translationX * parseInt(shadow.dataset.depth), 2917 y: mouseMoveValues.translationY * parseInt(shadow.dataset.depth) 2918 });
2919 }); 2920 2921 requestAnimationFrame(raf); 2922 } 2923 2924 requestAnimationFrame(raf); 2925 } 2926 2927 utility 2928 })(); 2929 2930 /* news page galley */ 2931 (() => { 2932 let newsGallery = null; 2933 let newsGalleryRows = null; 2934 let newsGalleryRowImages = null; 2935 2936 window.addEventListener('DOMContentLoaded', () => { 2937 newsGallery = document.querySelector('.js-news-gallery'); 2938 2939 if (newsGallery) { 2940 correctImagesHeight(); 2941 2942 window.addEventListener('resize', correctImagesHeight); 2943 } 2944 }); 2945 2946 function correctImagesHeight () { 2947 newsGalleryRows = [...document.querySelectorAll('.js-news-gallery-row')]; 2948 let rowNumber = 1; 2949 2950 newsGalleryRows.forEach(newsGalleryRow => { 2951 newsGalleryRowImages = [...newsGalleryRow.querySelectorAll('.js-photo-gallery-item')]; 2952 2953 if (window.innerWidth <= 1000) { 2954 newsGalleryRowImages.forEach((newsGalleryRowImage, index) => { 2955 if (newsGalleryRowImage.closest('.news-page__photo__box')) { 2956 newsGalleryRowImages.splice(index, 1); 2957 } 2958 }); 2959 } 2960 2961 let newsGalleryRowWidth = 0; 2962 let newsGalleryRowRatios = []; 2963 let newsGalleryRowMaxHeight = null; 2964 2965 newsGalleryRowWidth = newsGalleryRow.clientWidth - (newsGalleryRowImages.length - 1) * 10; 2966 2967 newsGalleryRowImages.forEach(function (newsGalleryRowImage) { 2968 let image = newsGalleryRowImage.querySelector('IMG'); 2969 let imageRatio = parseInt(image.getAttribute('width')) / parseInt(image.getAttribute('height')); 2970 newsGalleryRowRatios.push(imageRatio); 2971 if (newsGalleryRowMaxHeight == null || parseInt(image.getAttribute('height')) < newsGalleryRowMaxHeight) { 2972 newsGalleryRowMaxHeight = parseInt(image.getAttribute('height')); 2973 } 2974 }); 2975 2976 let targetHeight = newsGalleryRowMaxHeight; 2977 2978 if (rowNumber == 2) { 2979 while (checkRowWidth(newsGalleryRowRatios, targetHeight) >= newsGalleryRowWidth) { 2980 targetHeight = targetHeight - 0.5; 2981 } 2982 2983 newsGalleryRowImages.forEach(function (newsGalleryRowImage) { 2984 let image = newsGalleryRowImage.querySelector('IMG'); 2985 let imageRatio = parseInt(image.getAttribute('width')) / parseInt(image.getAttribute('height')); 2986 let itemWidth = imageRatio * targetHeight; 2987 image.style.setProperty('--item-width', `${itemWidth}px`); 2988 }); 2989 } else { 2990 let rowFactors = null; 2991 if (rowNumber == 1) { 2992 switch (newsGalleryRowImages.length) { 2993 case 1: 2994 rowFactors = [1]; 2995 case 2: 2996 rowFactors = [0.85, 1]; 2997 case 3: 2998 rowFactors = [0.85, 1, 0.7]; 2999 break; 3000 } 3001 } else if (rowNumber == 3) { 3002 switch (newsGalleryRowImages.length) { 3003 case 1: 3004 rowFactors = [1]; 3005 case 2: 3006 rowFactors = [1, 0.85]; 3007 case 3: 3008 rowFactors = [0.7, 1, 0.85]; 3009 break; 3010 } 3011 } 3012 3013 while (checkRowWidthVariable(newsGalleryRowRatios, rowFactors, targetHeight) >= newsGalleryRowWidth) { 3014 targetHeight = targetHeight - 0.5; 3015 } 3016 3017 newsGalleryRowImages.forEach(function (newsGalleryRowImage, index) { 3018 let image = newsGalleryRowImage.querySelector('IMG'); 3019 let imageRatio = parseInt(image.getAttribute('width')) / parseInt(image.getAttribute('height')); 3020 let itemWidth = imageRatio * targetHeight * rowFactors[index]; 3021 image.style.setProperty('--item-width', `${itemWidth}px`); 3022 }); 3023 } 3024 3025 rowNumber++; 3026 }); 3027 } 3028 3029 function checkRowWidth (ratios, height) { 3030 let width = 0; 3031 3032 ratios.forEach(function (ratio) { 3033 width += height * ratio; 3034 }); 3035 3036 return Math.round(width); 3037 } 3038 3039 function checkRowWidthVariable (ratios, factors, height) { 3040 let width = 0; 3041 3042 ratios.forEach(function (ratio, index) { 3043 width += height * ratio * factors[index]; 3044 }); 3045 3046 return Math.round(width); 3047 } 3048 })(); 3049 3050 (() => { 3051 let interval = setStepAnimation() 3052 3053 function setStepAnimation (step = 3) { 3054 let count = 0 3055 let calendarBtn = document.querySelector('.js-worship-calendar-button'); 3056 3057 if (calendarBtn) { 3058 return setInterval(function () { 3059 if (count === step) { 3060 calendarBtn.classList.add('animation') 3061 clearInterval(interval) 3062 3063 setTimeout(function () { 3064 calendarBtn.classList.remove('animation') 3065 interval = setStepAnimation() 3066 }, step * 1000) 3067 } 3068 count++ 3069 }, 1000) 3070 } 3071 } 3072 })(); 3073});
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.