PageSourceSearch

https://crescentclubandspa.com/wp-content/themes/crescent-clup-updated/assets/js/custom.js?ver=1789578991

js crescentclubandspa.com collected 2026-10-05 03:00:28 UTC 27,783 bytes, 664 lines download raw bytes

1/**
2 * Footer script migrated from the retired "Custom Codes" plugin (custom_public.js, save #364).
3 * Changes vs. the plugin copy: cl() is a no-op (was console.log), scrollToLinks guards $("#") (the
4 * only call that depended on jQuery Migrate, removed in P6), and the page checks accept
5 * slug-based body classes (page-dining-and-social, page-fitness-spa, home) added by
6 * includes/assets.php as alternates to page-id-11 / page-id-12 / page-template-page-home.
7 * Depends on jQuery, assets/js/vendors.min.js (gsap, ScrollTrigger, video.js, $.scrollLock, lazysizes)
8 * and the theme dist bundle (slick, magnificPopup).
9 */
10jQuery(document).ready(function($){
11    var $win = $(window),
12        $doc = $(document),
13        $html = $("html"),
14        $body = $("body"),
15        $header = $("header.header"),
16        $nav = $header.find("nav"),
17        $navBtn = $header.find(".menu-toggle"),
18		$footer = $("footer.footer"),
19        $siteContent = $(".main"),
20        isMobile = /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),
21        controller,//NEED TO REMOVE SCOLLMAGIC DEPENDENCIES
22        events = eventsObj();
23    var winWidth = $win.width(),
24        winHeight = $win.height(),
25        docHeight = $doc.height(),
26        scrollY = $win.scrollTop();
27    
28    
29    //-----------------------------------------------------------------------
30    //-- MODULES
31    //-----------------------------------------------------------------------
32    var modules = {
33        //---------------------------------
34        //-- PAGES
35        //---------------------------------
36        homePage: function() {
37            if (!$body.hasClass("page-template-page-home") && !$body.hasClass("home")) { return; }
38        },
39        wellnessPage: function() {
40            if (!$body.hasClass("page-id-12") && !$body.hasClass("page-fitness-spa")) { return; }
41            
42            $header.find(".scroll-to a").on("click", scrollToSection);
43            
44            
45            function scrollToSection(e) {
46                e.preventDefault();
47                var href = $(this).attr("href").replace("/wellness", ""),
48                    $section = $(href);
49                
50                if ($section.length) {
51                    events.emit("scroll_to_link_click");
52                    $html.add($body).animate({
53                        scrollTop: $section.offset().top
54                    }, 1000);
55                }
56            }
57            
58        },
59        fitnessSpa: function() {
60            if (!$body.hasClass("page-id-12") && !$body.hasClass("page-fitness-spa")) { return; }
61            
62            fitnessGallery();
63            
64            function fitnessGallery() {
65                var $sec = $siteContent.find("#fitness-center"),
66                    $galleryBtn = $sec.find(".js-fitness-gallery-trigger"),
67                    $jsonCnt = $siteContent.find(".fitness-gallery-json-cnt"),
68                    galleryItems = getGalleryItems(),
69                    $mfpCnt = null;cl("gallery items", galleryItems);
70                
71                var mfpGallery = $galleryBtn.magnificPopup({
72                    items: galleryItems,
73                    type: 'image',
74                    removalDelay: 300,
75                    mainClass: "mfp-fade",
76            		closeMarkup: '<button title="Close (Esc)" type="button" class="mfp-close"><span></span>Back to gallery</button>',
77                    gallery: {
78                    	enabled:true,
79                        navigateByImgClick: false
80                    },
81                    callbacks: {
82                        open: function() {//cl("gallery open");
83                        	$mfpCnt = $(".mfp-container");
84                            setupGalleryNav();
85                        },
86                        change: function() {//cl("gallery change");
87                            setupGalleryNav();
88                        },
89                        close: function() {
90                            $mfpCnt = null;
91                        }
92                    },
93                });
94                
95                function setupGalleryNav() {
96                    if ($mfpCnt === null) { return; }
97                    var $nav = $mfpCnt.find(".mfp-arrow"),
98                        currentIndex = $.magnificPopup.instance.index,
99                        prevItem = getPrevNext("prev", currentIndex),
100                        nextItem = getPrevNext("next", currentIndex),
101                        html = `<a href="#" class="section__image image-fit" style="position:absolute;"><img src="{{src}}" srcset="{{srcset}}" /></a>`;//cl("curr index", currentIndex);cl("prev",prevItem);cl("next", nextItem);
102                    
103                    $nav.filter(".mfp-arrow-left").empty().html(html.replace(/{{src}}/g, prevItem.src).replace(/{{srcset}}/g, prevItem.srcset));
104                    $nav.filter(".mfp-arrow-right").empty().html(html.replace(/{{src}}/g, nextItem.src).replace(/{{srcset}}/g, nextItem.srcset));
105                }
106                function getPrevNext(direction, index) {
107                    var prevNextIndex;
108                    
109                    if (direction === "prev") {
110                        prevNextIndex = (index == 0) ? galleryItems.length - 1 : pI(index) - 1;
111                    }
112                    else {
113                        prevNextIndex = (index == (galleryItems.length - 1)) ? 0 : pI(index) + 1;
114                    }
115                    return galleryItems[prevNextIndex];
116                }
117                function getGalleryItems() {
118                    var $jsonItems = $jsonCnt.find(".fitness-gallery-item-json"),
119                        gallery = [];
120                    
121                    $jsonItems.each(function() {
122                        var image = JSON.parse($(this).html());
123                        gallery.push({ src: image.src, srcset: image.srcset });
124                    });
125                    
126                    return gallery;
127                }
128            }
129        },
130        diningSocial: function() {
131            if (!$body.hasClass("page-id-11") && !$body.hasClass("page-dining-and-social")) { return; }
132            
133            featuresSlider();
134            
135            function featuresSlider() {
136                var $sec = $siteContent.find("section.section-features"),
137                    $imgSlider = $sec.find(".features-img-slider"),
138                    $contentSlider = $sec.find(".features-tabs-slider"),
139                    $tabLinks = $sec.find(".tab-title"),
140                    autoplaySpeed = pI($imgSlider.attr("data-speed")) || 3000;
141                
142                //Set tab link
143                $tabLinks.first().addClass("active");
144                //Init sliders
145                $imgSlider.slick({
146                    infinite: true,
147                    speed: 500,
148                    fade: true,
149                    cssEase: 'linear',
150                    appendArrows: $imgSlider.siblings('.slider__pages').find('.slider-nav-cnt'),
151                    asNavFor: $contentSlider,
152                    autoplay: false,
153                    //autoplayspeed: autoplaySpeed,
154                });
155                $contentSlider.slick({
156                    infinite: true,
157                    speed: 500,
158                    fade: true,
159                    cssEase: 'linear',
160                    arrows: false,
161                    asNavFor: $imgSlider
162                });
163                //Change tab on slider change
164                $imgSlider.on("beforeChange", function() {
165                    $tabLinks.removeClass("active");
166                });
167                $imgSlider.on("afterChange", function() {
168                    var activeIndex = $imgSlider.slick("slickCurrentSlide");//cl("slick after change", activeIndex);
169                    $tabLinks.eq(activeIndex).addClass("active");
170                });
171                //Change slider on tab link click
172                $tabLinks.on("click", function() {
173                    $imgSlider.slick("slickGoTo", $(this).index());
174                });
175            }
176        },
177        
178        //---------------------------------
179        //-- SECTIONS
180        //---------------------------------
181      	heroVideoSections: function() {
182      		var $sec = $(".hero-video");
183            if (!$sec.length) { return; }
184            
185            var $vidCnt = $sec.find(".video-cnt"),
186                poster = $vidCnt.attr("data-poster"),
187                video = (mq("landscape")) ? $vidCnt.attr("data-video-h") : $vidCnt.attr("data-video-v"),
188                html = `<video id="hero-video" class="video-js" controls preload="auto" poster="${poster}" muted playsinline autoplay>
189                          <source src="${video}" type="video/mp4">
190                          <p class="vjs-no-js">
191                            To view this video please enable JavaScript, and consider upgrading to a
192                            web browser that
193                            <a href="https://videojs.com/html5-video-support/" target="_blank">
194                              supports HTML5 video
195                            </a>
196                          </p>
197                        </video>`,
198                buttons = `<button class="pause-btn js-pause-play active" title="pause video"><span class="screenreader">Pause Video</span></button>
199            			   <button class="play-btn js-pause-play" title="pause video"><span class="screenreader">Pause Video</span></button>`;
200            
201            $vidCnt.append(html);
202            var options = { autoplay: 'muted', loop: true , controls: false };
203            var player = videojs('hero-video', options, onPlayerReady);
204            
205            $sec.append(buttons).on("click", ".js-pause-play", togglePausePlay);
206            
207            function onPlayerReady() {//videojs.log('Your player is ready!');
208				$vidCnt.removeClass("vis-h");
209                var promise = this.play();
210
211                if (promise !== undefined) {
212                    promise.then(function() {
213                      // Autoplay started!
214                    }).catch(function(error) {cl("video autoplay error", error);
215                      // Autoplay was prevented.
216                    });
217                }
218
219                this.on('ended', function() {
220                	//videojs.log('video ended');
221                });
222            }
223            function togglePausePlay() {
224                var $this = $(this),
225                    isPause = $this.hasClass("pause-btn");
226                if (isPause)
227                    player.pause();
228                else
229                    player.play();
230                
231                $sec.find(".js-pause-play").toggleClass("active");
232            }
233        },
234        jsSliders: function() {
235            var $sliders = $(".js-slider, .js-slider-alt").find(".slider__slides");
236            
237            $sliders.each(function() {
238                var $slider = $(this),
239                    $titles = $slider.siblings(".slider__pages").find("h3");
240                    
241                $slider.on("beforeChange", removeCurrent);
242                $slider.on('afterChange', updateTitles);
243                $titles.on("click", changeSlide);
244            
245                function removeCurrent() {
246                    $titles.removeClass("is-current");
247                }
248            	function updateTitles(event, slick, currentSlide) {
249                    $titles.eq(currentSlide).addClass("is-current");
250                }
251                function changeSlide() {
252                    if (mq("min-width:1024px")) {
253                        $slider.slick('slickGoTo', $(this).index() - 1);
254                    }
255                }
256            });
257        },
258        
259        accordionsMenu: function() {
260            var $sec = $siteContent.find("section.section-menu"),
261                $accordions = $sec.find(".table-menu"),
262            	$accordionsDinning = $sec.find(".list-menu");
263            
264            
265            $accordions.each(addSpacer);
266            $accordions.on("click", "h4", toggleAccordion);
267            
268            //Dinning & Social page
269            $accordionsDinning.each(showFirst);
270            $accordionsDinning.on("click", "h4", toggleAccordionDinning);
271            
272            function addSpacer() {
273                var $this = $(this);
274                if ($this.is(":first-child")) {
275                    $this.addClass("active").find(".table").show();
276                }
277                $('<div class="spacer"></div>').insertAfter($this.find("h4"));
278            }
279            
280            function showFirst() {
281                var $this = $(this);
282                if ($this.is(":first-child")) {
283                    $this.addClass("active").find(".items").show();
284                }
285            }
286            
287            function toggleAccordion() {
288                var $header = $(this),
289                    $parent = $header.parent(),
290                    $content = $parent.find(".table");
291                
292                if ($parent.hasClass("active")) {
293                    $content.slideUp();
294                    $parent.removeClass("active");
295                }
296                else {
297                    $content.slideDown();
298                    $parent.addClass("active");
299                }
300            }
301           
302            
303            function toggleAccordionDinning() {
304                var $header = $(this),
305                    $parent = $header.parent(),
306                    $content = $parent.find(".items");
307                
308                if ($parent.hasClass("active")) {
309                    $content.slideUp();
310                    $parent.removeClass("active");
311                }
312                else {
313                    $content.slideDown();
314                    $parent.addClass("active");
315                }
316            }
317            
318        },
319        //---------------------------------
320        //-- SITE
321        //---------------------------------
322        navTrigger: function() {
323            /*$navBtn.on("click", toggleMenu);
324            $nav.find(".close-btn").on("click", closeMenu);            
325            $win.resize(closeMenu);
326            events.on("scroll_to_link_click", closeMenu);*/
327            
328            function toggleMenu() {
329                $navBtn.toggleClass("active");
330                $nav.toggleClass("open", $navBtn.hasClass("active"));
331                $body.toggleClass("nav-open", $navBtn.hasClass("active"));
332                $.scrollLock($navBtn.hasClass("active"));
333            }
334            function closeMenu() {
335                $navBtn.removeClass("active");
336                $nav.removeClass("open");
337                $body.removeClass("nav-open");
338                $.scrollLock(false);
339            }
340        },
341        scrollToLinks: function() {
342            var $scrollToLinks = $('a[href^="#"], a[href^="/#"]').not(".no-scrollto");
343
344            $scrollToLinks.on("click", function(e) {
345                var href = $(this).attr("href").replace("/", ""),
346                    $section = (href === "#") ? $() : $(href);//jQuery 3 without Migrate throws on $("#"); Migrate used to return an empty set here
347
348                if (href == "#" || $section.length) { e.preventDefault(); }
349                if ($section.length) {
350                    events.emit("scroll_to_link_click");
351                    $html.add($body).animate({
352                        scrollTop: $section.offset().top
353                    }, 1000);
354                    //Accessibility
355                    if ($section.is("a, select, input, textarea, button")) { $section.focus(); }
356                }
357                else if (href.includes("#")) {
358                   cl("no match", href);
359                }
360            });
361        },//scrollToLinks()
362        fadeOnScroll: function() {
363            var $elements = $(".onscroll.fadein");
364            if (!$elements.length) { return; }
365            
366            $elements.each(function() {
367                var $this = $(this),
368                    trigger = ( $this.attr("data-onscroll-trigger") ) ? $this.attr("data-onscroll-trigger") : $this[0],
369                    triggerStart = ( $this.attr("data-onscroll-triggerstart") ) ? $this.attr("data-onscroll-triggerstart") : "top center",
370                    duration = ( $this.attr("data-onscroll-duration") ) ? pI( $this.attr("data-onscroll-duration") ) : 1;
371                gsap.set($this, { autoAlpha: 0 });
372                gsap.to($this, {
373                	scrollTrigger: { trigger: trigger, start: triggerStart },
374                  	autoAlpha: 1,
375                    duration: duration,
376                    onComplete: clearProps,
377                    onCompleteParams: [$this]
378                });
379                
380                function clearProps($target) {
381                    gsap.set($target, { clearProps: "opacity,visibility" });
382                }
383            });
384        },
385        modalTrigger: function() {
386            var $modal = $(".modal");
387            
388            $modal.appendTo($body);
389            $doc.on("click", ".js-modal-trigger", openModal);
390            $doc.on("click", ".modal .close-btn", closeModal);
391            $win.on("resize", closeModal);
392            
393            function openModal() {
394                var $target = $(`.modal${$(this).attr("data-target")}`);
395                if (!$target.length) { cl(`no modal target: ${$(this).attr("data-target")}`); return; }
396                    
397               	$target.addClass("open");
398                $body.addClass("modal-open");
399                $.scrollLock(true);
400            }
401            function closeModal() {
402                $(".modal").removeClass("open");
403                $body.removeClass("modal-open");
404                $.scrollLock(false);
405            }
406        },
407        //---------------------------------
408        //-- GLOBAL
409        //---------------------------------
410        window: function() {
411            //-- Scroll
412            var ticking = false;
413            $win.on("scroll", handleScrolling);
414            function handleScrolling(e) {
415                if (!ticking) {
416                    window.requestAnimationFrame(function() {
417                        updateScrollPos();
418                        ticking = false;
419                    });
420                    ticking = true;
421                }
422            }
423            function updateScrollPos() {
424                var scrollTop = $win.scrollTop();
425                if (scrollY == scrollTop) { return; }//only update if scroll position has changed
426                scrollY = scrollTop;
427                events.emit("scrollYChanged");
428            }
429
430            //-- Resize
431            $win.on("resize", checkVariables);
432            function checkVariables() {
433                if (winWidth != $win.width()) {
434                    updateWidth();
435                }
436                if (winHeight != $win.height()) {
437                    updateHeight();
438                }
439            }
440            function updateWidth() {
441                winWidth = $win.width();
442                events.emit("winWidthChange");
443            }
444            function updateHeight() {
445                winHeight = $win.height();
446                events.emit("winHeightChanged");
447            }
448        },//window()
449        document: function() {
450            //-- Document Height
451            $win.on("resize", updateDocHeight);
452            events.on("elHeightChange", updateDocHeight);
453            function updateDocHeight() {
454                var newDocHeight = $doc.height();
455                if (newDocHeight != docHeight) {
456                    docHeight = newDocHeight;
457                    events.emit("docHeightChanged", docHeight);
458                }
459            }
460        },//document()
461        body: function() {
462            var atTopVal = 0,
463                lastScrollY = scrollY;
464
465            setup();
466            events.on("scrollYChanged", updateScrollClasses);
467
468            function setup() {
469                 //== Initial setup
470                (scrollY <= atTopVal) ? $body.addClass("at-top") : $body.removeClass("at-top");
471                ((scrollY + winHeight) == docHeight) ? $body.addClass("at-bottom") : $body.removeClass("at-bottom");
472                $body.addClass("ready");
473            }
474            function updateScrollClasses() {
475                //If scrolling up or down
476                (lastScrollY > scrollY) ? $body.removeClass("scrolling-down").addClass("scrolling-up") : $body.addClass("scrolling-down").removeClass("scrolling-up");
477                //If at top of page
478                (scrollY <= atTopVal) ? $body.removeClass("scrolling-down").removeClass("scrolling-up").addClass("at-top") : $body.removeClass("at-top");
479                //If at bottom of page
480                ((scrollY + winHeight + 1) >= docHeight) ? $body.addClass("at-bottom") : $body.removeClass("at-bottom");//console.log("scrollTop + windowHeight:", (scrollTop + winHeight + 1))
481                //Update lastScrollY var
482                lastScrollY = scrollY;
483            }
484        },//body()
485    };
486
487
488    //-----------------------------------------------------------------------
489    //-- HELPER FUNCTIONS
490    //-----------------------------------------------------------------------
491    //-- Events Object Setup --//
492    function eventsObj() {
493        return {
494            events: {},
495            on: function(eventName, fn) {
496                this.events[eventName] = this.events[eventName] || [];
497                this.events[eventName].push(fn);
498            },
499            off: function(eventName, fn) {
500                if (this.events[eventName]) {
501                    for (var i = 0; i < this.events[eventName].length; i++) {
502                        if (this.events[eventName][i] === fn) {
503                            this.events[eventName].splice(i, 1);
504                            break;
505                        }
506                    };
507                }
508            },
509            emit: function(eventName, data) {
510                if (this.events[eventName]) {
511                    this.events[eventName].forEach(function(fn) {
512                        fn(data);
513                    });
514                }
515            }
516        };
517    }
518    //-- Console Log Shortcut --//
519    function cl() {
520        /* no-op: debug console.log() shortcut disabled for production (was console.log passthrough) */
521    }
522    //-- Media Matches Shortcut --//
523    function mq(mediaQuery) {
524        switch (mediaQuery) {
525            case "phone": mediaQuery = "(max-width: 767px), screen and (max-width: 812px) and (orientation: landscape)"; break;
526            case "not phone": mediaQuery = "(min-width: 768px)"; break;
527            case "tablet": mediaQuery = "(max-width: 1023px)"; break;
528            case "desktop": mediaQuery = "(min-width: 1024px)"; break;
529            case "portrait": mediaQuery = "(orientation: portrait)"; break;
530            case "landscape": mediaQuery = "(orientation: landscape)"; break;
531            default: mediaQuery = mediaQuery;
532        }
533        mediaQuery = (!mediaQuery.includes("(") && !mediaQuery.includes(")")) ? `(${mediaQuery})` : mediaQuery;//if forget to put ()
534        return window.matchMedia(mediaQuery).matches;
535    }
536    //-- Detect Mobile Devices --//
537    function mobileDevice(device) {
538        var deviceCheck;
539        switch(device) {
540            case 'android':
541                deviceCheck = /Android/i.test(navigator.userAgent);
542                break;
543            case 'iOS':
544                deviceCheck = /iPhone|iPad|iPod/i.test(navigator.userAgent);
545                break;
546            default:
547                deviceCheck = /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
548        };
549        return deviceCheck;
550    }
551    //-- Parse Int Shortcut --//
552    function pI(int) {
553        return parseInt(int);
554    }
555    //-- Parse Float Shortcut --//
556    function pF(int) {
557        return parseFloat(int);
558    }
559    //-- GetBoundingClientRect Shortcut --//
560    function getBound(el) {//takes dom obj or jquery obj
561        var node = (typeof el === "string") ? document.querySelector(el) : (el instanceof jQuery) ? el[0] : el;
562        return node.getBoundingClientRect();
563    }
564    //-- JSON String --//
565    function isJson(str) {
566        try { JSON.parse(str); }
567        catch(err) { return false; }
568        return true;
569    }
570    //-- jQuery Shuffle Method (need to call before use) --//
571    function $shuffle() {
572        //-- Shuffle an array of jQuery elements --//
573        $.fn.shuffle = function() {
574            var allElems = this.get(),
575                getRandom = function(max) {
576                    return Math.floor(Math.random() * max);
577                },
578                shuffled = $.map(allElems, function(){
579                    var random = getRandom(allElems.length),
580                        randEl = $(allElems[random]).clone(true)[0];
581                    allElems.splice(random, 1);
582                    return randEl;
583               });
584
585            this.each(function(i){
586                $(this).replaceWith($(shuffled[i]));
587            });
588
589            return $(shuffled);
590        };
591    }
592    //-- Check if el in viewport --//
593    function isInViewport(el) {
594        var bounding = el.getBoundingClientRect(),//console.log("el",el);console.log("bounding",bounding);
595            isVisible = (
596            //Y Axis
597            (
598                (bounding.top >= 0 && bounding.top <= winHeight)
599                ||
600                (bounding.bottom >= 0 && bounding.bottom <= winHeight)
601            )
602        );//console.log("isVisible",isVisible);
603        return isVisible;
604    }
605    //-- Get scroll position as percentage (how far scrolled down page) --//
606    function getScrolledPercent(round = false) {
607        var scrollableLength = docHeight - winHeight,
608            scrollFraction = scrollableLength / 100,
609            scrolledAmount = scrollY / scrollFraction;//cl(`scrolled percent: ${scrolledAmount}`);
610        return (round) ? Math.round(scrolledAmount) : scrolledAmount;
611    }
612    //-- Get Scroll Element Trigger Point --//
613    function getScrollTriggerPoint($el, triggerOffset = 0, triggerHook = "onEnter") {
614        var offset = $el.offset(),
615            screenOffset = getScreenOffset(),
616            scrollTriggerPoint = offset.top;
617
618        //Screen Offset
619        scrollTriggerPoint-=screenOffset;
620        //Trigger Offset
621        scrollTriggerPoint = (typeof triggerOffset === "number") ? scrollTriggerPoint + triggerOffset : scrollTriggerPoint;
622
623        return (scrollTriggerPoint > 0) ? scrollTriggerPoint : 0;
624
625        function getScreenOffset() {
626            var hookOffset;
627            if (typeof triggerHook === "string") {
628                switch(triggerHook) {
629                    case "onCenter":
630                        hookOffset = winHeight / 2;
631                        break;
632                    case "onLeave":
633                        hookOffset = 0;
634                        break;
635                    default://"onEnter"
636                        hookOffset = winHeight;
637                }
638            }
639            else {
640                hookOffset = (typeof triggerHook === "number" && triggerHook <= 1 && triggerHook >= 0) ? triggerHook * winHeight : winHeight;
641            }
642            return hookOffset;
643        }
644    }
645	//-- Run Modules --//
646    function runModules() {
647        $.each(modules, function() { this(); });
648    }
649
650
651
652    //-----------------------------------------------------------------------
653    //-- INIT
654    //-----------------------------------------------------------------------
655    if (window.WUA.assets.isLoaded) {
656        runModules();
657    }
658    else {
659        window.WUA.events.on("wua_assets_loaded", runModules);
660    }
661    //events.emit("siteReady");cl("siteReady");
662    
663
664}); // document ready

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.