PageSourceSearch

https://barunnamu-hospital.vercel.app/assets/basic.js

js barunnamu-hospital.vercel.app collected 2026-10-03 06:10:34 UTC 15,398 bytes, 483 lines download raw bytes

1let lenis;
2let lenisRafId;
3
4// Lenis 초기화 함수
5function initLenis() {
6    if (!lenis && window.innerWidth > 1240) {
7        lenis = new Lenis({
8            duration: 1.2,
9            infinite: false,
10            gestureOrientation: "vertical",
11            normalizeWheel: false,
12            smoothTouch: true
13        });
14
15        function raf(time) {
16            lenis.raf(time);
17            lenisRafId = requestAnimationFrame(raf);
18        }
19
20        lenisRafId = requestAnimationFrame(raf);
21
22        addScrollEventListeners();
23    }
24}
25
26// Lenis 제거 함수
27function destroyLenis() {
28    if (lenis) {
29        cancelAnimationFrame(lenisRafId);
30        lenis.destroy();
31        lenis = null;
32        lenisRafId = null;
33
34        removeScrollEventListeners();
35    }
36}
37
38
39// 내부 스크롤 가능한 요소 이벤트 리스너 추가
40function addScrollEventListeners() {
41    const scrollableContainers = document.querySelectorAll(
42        '.flagship_sub .building_sect .info_cont, .depart_map_sect .map_cont .aside .map_li'
43    );
44    scrollableContainers.forEach((container) => {
45        container.addEventListener('wheel', handleWheelEvent, {passive: false});
46    });
47}
48
49// 내부 스크롤 가능한 요소 이벤트 리스너 제거
50function removeScrollEventListeners() {
51    const scrollableContainers = document.querySelectorAll(
52        '.flagship_sub .building_sect .info_cont, .depart_map_sect .map_cont .aside .map_li'
53    );
54    scrollableContainers.forEach((container) => {
55        container.removeEventListener('wheel', handleWheelEvent);
56    });
57}
58
59
60
61// 리사이즈 시 Lenis 활성화/비활성화
62window.addEventListener("resize", () => {
63    if (window.innerWidth > 1240) {
64        initLenis(); // PC 화면에서는 Lenis 초기화
65    }else {
66        destroyLenis(); // 모바일 화면에서는 Lenis 비활성화
67    }
68});
69
70// Lenis 스크롤 애니메이션 프레임 관리
71function smoothScroll() {
72    function raf(time) {
73        if (lenis) lenis.raf(time);
74        requestAnimationFrame(raf);
75    }
76
77    requestAnimationFrame(raf);
78}
79
80$(document).ready(function () {
81    // 초기 설정
82    initLenis();
83
84    if (window.matchMedia("(min-width: 768px)").matches) {
85        new WOW().init();
86    }
87
88    /*header*/
89    // $('.gnb_bg').css('width',$('body').innerWidth());
90    // $(window).resize(function(){
91    //     $('.gnb_bg').css('width',$('body').innerWidth());
92    // });
93
94    //top_btn
95    $(".top_btn").click(function () {
96        setTimeout(() => {
97
98            if (lenis) {
99                lenis.scrollTo(0, {immediate: true}); // 상단으로 즉시 스크롤
100            }else {
101                window.scrollTo({
102                    top: 0,
103                    behavior: 'smooth'
104                });
105            }
106
107        }, 100); // 페이지 로드 완료 후 약간의 지연 후 강제로 스크롤 이동
108
109        return false;
110    });
111
112
113    // 새로고침 시 스크롤을 상단으로 강제 이동
114    window.addEventListener('load', () => {
115        header();
116    });
117
118
119    function header() {
120
121        var previousScroll;
122        var windowScroll = window.pageYOffset || document.documentElement.scrollTop;
123
124        $(window).scroll(function () {
125            var currentScroll = $(this).scrollTop();
126
127
128            if (currentScroll > previousScroll) {
129                $(".header").addClass("scroll_down")
130            } else {
131                $(".header").removeClass("scroll_down")
132            }
133
134            previousScroll = currentScroll;
135
136
137            if (window.scrollY <= 100) {
138                $(".header").addClass("top")
139                $(".header").removeClass("down")
140
141            } else {
142                $(".header").removeClass("top")
143                $(".header").addClass("down")
144
145            }
146
147        });
148
149    }
150
151    $("select").niceSelect();
152    
153
154});
155
156
157
158//모바일 이미지 확대
159document.addEventListener('DOMContentLoaded', function() {
160    // 모달 HTML 생성
161    const modalHTML = `
162        <div class="zoom-modal">
163            <div class="zoom-modal-content">
164                <img>
165                <button class="zoom-modal-close">
166                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" height="0.8em"><path d="M324.5 411.1c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6L214.6 256 347.1 123.5c6.2-6.2 6.2-16.4 0-22.6s-16.4-6.2-22.6 0L192 233.4 59.6 100.9c-6.2-6.2-16.4-6.2-22.6 0s-6.2 16.4 0 22.6L169.4 256 36.9 388.5c-6.2 6.2-6.2 16.4 0 22.6s16.4 6.2 22.6 0L192 278.6 324.5 411.1z"/></svg>
167                </button>
168            </div>
169        </div>
170    `;
171    document.body.insertAdjacentHTML('beforeend', modalHTML);
172
173    const modal = document.querySelector('.zoom-modal');
174    const modalImg = modal.querySelector('img');
175    const closeBtn = modal.querySelector('.zoom-modal-close');
176
177    /*
178    // 이미지 클릭 이벤트
179    if(window.innerWidth <= 768){
180        document.querySelectorAll('.mo_img_zoom').forEach(container => {
181            const images = container.querySelectorAll('img');
182            if (images) {
183                container.addEventListener('click', () => {
184                    // 보이는 이미지만 선택
185                    const visibleImg = Array.from(images).find(img => {
186                        const style = window.getComputedStyle(img);
187                        return style.display !== 'none';
188                    });
189
190                    if (visibleImg) {
191                        modal.style.display = 'block';
192                        modalImg.src = visibleImg.src;
193                    }
194                });
195            }
196        });
197
198        // 닫기 이벤트
199        closeBtn.addEventListener('click', e => {
200            e.stopPropagation();
201            modal.style.display = 'none';
202        });
203
204        modal.addEventListener('click', e => {
205            if (e.target === modal) {
206                modal.style.display = 'none';
207            }
208        });
209    }
210    */
211
212});
213
214// 특화센터 > 질환 원인
215let causeSlide = null;
216
217function initCauseSlide() {
218    const container = document.querySelector('.cause_wrap .swiper-container');
219    if (!container) {
220        console.warn("Swiper 컨테이너 요소가 없습니다. init
220CauseSlide 실행 중단.");
221        return; // 요소가 없으면 함수 실행 중단
222    }
223
224    const slideCount = container.querySelectorAll('.swiper-slide').length;
225    const isMobile = window.matchMedia("(max-width: 1240px)").matches;
226
227    if (slideCount >= 7) {
228        if (!causeSlide) {
229            causeSlide = new Swiper('.cause_wrap .swiper-container', {
230                slidesPerView: 'auto',
231                observer: true,
232                observeParents: true,
233            });
234        }
235    } else {
236        if (isMobile) {
237            if (!causeSlide) {
238                causeSlide = new Swiper('.cause_wrap .swiper-container', {
239                    slidesPerView: 'auto',
240                    observer: true,
241                    observeParents: true,
242                });
243            }
244        } else {
245            if (causeSlide) {
246                causeSlide.destroy(true, true);
247                causeSlide = null;
248            }
249        }
250    }
251}
252
253// 리사이즈 이벤트 바인딩
254function setupResizeListener() {
255    window.addEventListener('resize', initCauseSlide);
256}
257
258
259
260
261// 특화센터 > 주요 증상 탭 이벤트 초기화 함수
262function initCauseTabs() {
263    const causeTabs = document.querySelectorAll('.cause_tab button');
264    const causeTabConts = document.querySelectorAll('.cause_tab_cont');
265
266    if (causeTabs.length === 0 || causeTabConts.length === 0) {
267        console.warn("탭 버튼 또는 탭 콘텐츠를 찾을 수 없습니다. initCauseTabs 실행을 건너뜁니다.");
268        return;
269    }
270
271    causeTabs.forEach(tab => {
272        tab.addEventListener('click', () => {
273            // 1. 모든 탭에서 active 클래스 제거
274            causeTabs.forEach(t => t.classList.remove('active'));
275
276            // 2. 모든 탭 콘텐츠 숨기기
277            causeTabConts.forEach(content => content.classList.remove('active'));
278
279            // 3. 현재 클릭된 탭에 active 클래스 추가
280            tab.classList.add('active');
281
282            // 4. 해당하는 탭 콘텐츠 보여주기
283            const tabIndex = tab.getAttribute('data-cause-tab');
284            const targetContent = document.querySelector(`.cause_tab_cont${tabIndex}`);
285            if (targetContent) {
286                targetContent.classList.add('active');
287            }
288        });
289    });
290
291    // 초기화: 각 탭 콘텐츠에 대해 서브 탭 설정
292    causeTabConts.forEach(causeTabCont => {
293        updateSubTabs(causeTabCont);
294    });
295}
296
297// 특화센터 > 주요 증상 서브 탭 이벤트 초기화 함수
298function updateSubTabs(parent) {
299    const subTabs = parent.querySelectorAll('.cause_tab_in_tab button');
300    const subTabConts = parent.querySelectorAll('.tab_in_tab_cont');
301
302    if (subTabs.length === 0 || subTabConts.length === 0) {
303        console.warn(`"${parent.className}"에서 서브 탭 또는 서브 콘텐츠를 찾을 수 없습니다.`);
304        return;
305    }
306
307    subTabs.forEach(subTab => {
308        subTab.addEventListener('click', () => {
309            // 1. 모든 서브 탭에서 active 클래스 제거
310            subTabs.forEach(t => t.classList.remove('active'));
311
312            // 2. 모든 서브 콘텐츠 숨기기
313            subTabConts.forEach(content => content.classList.remove('active'));
314
315            // 3. 현재 클릭된 서브 탭에 active 클래스 추가
316            subTab.classList.add('active');
317
318            // 4. 해당하는 서브 콘텐츠 보여주기
319            const subTabIndex = subTab.getAttribute('data-cause-sub-tab');
320            const targetContent = parent.querySelector(`.tab_in_tab_cont${subTabIndex}`);
321            if (targetContent) {
322                targetContent.classList.add('active');
323            }
324        });
325    });
326}
327
328
329
330// 특화센터 > 치료법 아코디언 타입
331function initAccordion(selector = '.accordion_wrap') {
332    const $accordions = $(selector);
333
334    if ($accordions.length === 0) {
335        console.warn(`${selector} 요소를 찾을 수 없습니다. initAccordion 실행을 건너뜁니다.`);
336        return;
337    }
338
339    $accordions.each(function () {
340        const $accordion = $(this);
341        const $items = $accordion.find('.item');
342        const $headers = $accordion.find('.acc_tit');
343
344        $headers.on('click', function () {
345            const $item = $(this).parent('.item');
346            const $content = $item.find('.acc_cont');
347
348            // 모든 내용 숨기기
349            $items.find('.acc_cont').slideUp(0);
350
351            if ($item.hasClass('active')) {
352                // 이미 활성화된 항목은 비활성화
353                $item.removeClass('active');
354            } else {
355                // 다른 항목 비활성화 후 선택된 항목 활성화
356                $items.removeClass('active');
357                $item.addClass('active');
358                $content.slideDown(0);
359            }
360
361            // 스크롤 이동
362            const scrollTopOffset = $(this).offset().top;
363            const headerHeight = $(".header").outerHeight() || 0;
364            const targetPosition = Math.max(scrollTopOffset - headerHeight, 0);
365
366            if (window.innerWidth > 1240) {
367                if (typeof lenis !== "undefined" && lenis.scrollTo) {
368                    lenis.scrollTo(targetPosition, {
369                        duration: 0.5, // 0.5초 동안 스크롤
370                        easing: (t) => 1 - Math.pow(1 - t, 3), // 부드러운 가속도 적용
371                    });
372                } else {
373                    console.warn("Lenis 스크롤 객체가 정의되지 않았습니다.");
374                }
375            } else {
376                window.scrollTo({
377                    top: targetPosition,
378                    behavior: 'smooth' // 부드러운 스크롤
379                });
380            }
381        });
382    });
383}
384
385
386
387// 특화센터 > qna 타입
388function initQnaEvent(selector = '.qna_wrap') {
389    const $qnaWrap = $(selector);
390
391    if ($qnaWrap.length === 0) {
392        console.warn(`${selector} 요소를 찾을 수 없습니다. initQnaEvent 실행을 건너뜁니다.`);
393        return;
394    }
395
396    // 클릭 이벤트 바인딩
397    $qnaWrap.off('click').on('click', '.item .question', function () {
398        let $parent = $(this).parent('.item');
399        let $answer = $parent.find('.answer');
400
401        // 현재 열려있는 모든 답변 닫기 (현재 선택된 항목 제외)
402        $qnaWrap.find('.item').not($parent).removeClass('active');
403        $qnaWrap.find('.item .answer').not($answer).stop(true, true).slideUp(400);
404
405        // 현재 항목 토글
406        if ($parent.hasClass('active')) {
407            $parent.removeClass('active');
408            $answer.stop(true, true).slideUp(400);
409        } else {
410            $parent.addClass('active');
411            $answer.stop(true, true).slideDown(400);
412        }
413    });
414
415    // 리사이즈 이벤트 바인딩 (모바일 환경에서 강제로 닫히지 않도록 개선)
416    $(window).off(`resize.qnaResize.${selector}`).on(`resize.qnaResize.${selector}`, function () {
417        // 현재 화면의 너비가 변경되었는지 확인 (resize가 브라우저 주소창 숨김/표시가 아닌 경우)
418        const currentWidth = window.innerWidth;
419
420        // 이전 너비와 비교
421        if (typeof window._prevWidth === 'undefined' || window._prevWidth !== currentWidth) {
422            window._prevWidth = currentWidth; // 현재 너비 저장
423
424            // 리사이즈 시 답변의 display, height 초기화 및 active 클래스 제거
425            $qnaWrap.find('.item').each(function () {
426                $(this).removeClass('active'); // active 클래스 제거
427                $(this).find('.answer').css({
428                    display: '', // display 속성 초기화
429                    height: '',  // height 속성 초기화
430                });
431            });
432        }
433    });
434}
435
436
437
438
439
440// 특화센터 > checkpoint 타입
441function initCheckpointEvent() {
442    const $checkpointWrap = $('.checkpoint.swiper-container');
443
444    if ($checkpointWrap.length === 0) {
445        console.warn('.checkpoint.swiper-container 요소를 찾을 수 없습니다. initCheckpointEvent 실행을 건너뜁니다.');
446        return;
447    }
448
449    let checkpointSlide = null;
450
451    // Checkpoint 슬라이드 초기화 함수
452    function initCheckpointSlide() {
453        const isMobile = window.innerWidth <= 768;
454
455        if (isMobile) {
456            // 768px 이하에서 Swiper 초기화
457            if (!checkpointSlide) {
458                checkpointSlide = new Swiper('.checkpoint.swiper-container', {
459                    slidesPerView: 'auto',
460                    speed: 750,
461                    observer: true,
462                    observeParents: true,
463                });
464            }
465        } else {
466            // 768px 초과에서 Swiper 제거
467            if (checkpointSlide && typeof checkpointSlide.destroy === 'function') {
468                checkpointSlide.destroy(true, true);
469                checkpointSlide = null;
470            }
471        }
472    }
473
474    // 초기 실행
475    initCheckpointSlide();
476
477    // 리사이즈 이벤트 바인딩
478    $(window).off('resize.checkpointResize').on('resize.checkpointResize', function () {
479        initCheckpointSlide();
480    });
481}
482
483

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.