PageSourceSearch

https://adrhome.reb.or.kr/user/resources/main/js/common.js

js reb.or.kr collected 2026-10-01 12:04:54 UTC 15,275 bytes, 581 lines download raw bytes

1$(document).ready(function () {
2
3	//건너뛰기 포커스 이동
4	$(".skip_nav:eq(0)").click(function () {
5		$("#container").attr("tabindex", -1).focus();
6	});
7	$(".skip_nav:eq(1)").click(function () {
8		$("#gnb-box").attr("tabindex", -1).focus();
9	});
10	$(".skip_nav:eq(2)").click(function () {
11		$("#footer").attr("tabindex", -1).focus();
12	});
13
14
15	// 기본 스크롤 효과
16	let lenis;
17
18	function smoothScrollLenis() {
19		lenis = new Lenis({
20			duration: 2,
21			easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
22		});
23
24		function raf(time) {
25			lenis.raf(time);
26			requestAnimationFrame(raf);
27		}
28		requestAnimationFrame(raf);
29	}
30	if (typeof Lenis !== 'undefined') {
31		smoothScrollLenis();
32	} else {
33		if (window.console && console.warn) console.warn('Lenis not loaded; smooth scroll disabled');
34	}
35
36	// GSAP 안전 폴백: gsap 또는 ScrollTrigger가 로드되지 않았을 때 에러를 방지
37	if (typeof window.gsap === 'undefined') {
38		window.gsap = {
39			set: function() {},
40			to: function() {},
41			timeline: function() { return { to: function() { return this; } }; },
42			registerPlugin: function() {}
43		};
44		if (typeof window.ScrollTrigger === 'undefined') {
45			window.ScrollTrigger = {
46				matchMedia: function() {},
47				create: function() { return { kill: function() {} }; }
48			};
49		}
50		if (window.console && console.warn) console.warn('gsap or ScrollTrigger not loaded; animations disabled (fallback applied)');
51	}
52
53	const header = document.querySelector('header');
54
55	window.addEventListener('scroll', () => {
56		if (window.scrollY > 0) {
57			header.classList.add('is-scroll');
58		} else {
59			header.classList.remove('is-scroll');
60		}
61	});
62
63
64	// 헤더 높이만큼 #wrap 조절
65	function setWrapPadding() {
66		$('#wrap').css('padding-top', $('.header').outerHeight());
67		$('.mbtn-box .mgnb-con .mgnb-box').css('margin-top', $('.header').outerHeight());
68	}
69
70	setWrapPadding();
71
72	$(window).on('resize', setWrapPadding);
73
74	/******************* PC GNB *******************/
75	$('.gnb').on('mouseenter mouseover', function () {
76		$(this).addClass('on');
77		$('.header').addClass('on');
78	});
79
80	$('.gnb').on('mouseleave', function () {
81		$('.gnb').removeClass('on');
82		$('.header').removeClass('on');
83	});
84
85	$('.dep2-tit').hover(
86		function () {
87			$(this).closest('.dep1').find('.gnb-tit').addClass('on');
88		},
89		function () {
90			$(this).closest('.dep1').find('.gnb-tit').removeClass('on');
91		}
92	);
93
94
95
96
97	/******************* Mobile GNB *******************/
98	$(".mgnb").html($('.gnb-box').html());
99	$(".mgnb-search").html($('.header .search-wrap').html());
100
101	$('.mbtn-box .mbtn-btn').on('click', function () {
102		$(this).toggleClass('on');
103		$(this).next('.mgnb-con').toggleClass('on');
104
105		if ($(this).next('.mgnb-con').hasClass('on')) {
106			$(this).attr('title', '사이트맵 닫기');
107			$('body').addClass('overflow-hidden');
108			$('.mbtn-box').on('wheel', function(e) {
109				e.stopPropagation(); // 이벤트 버블링 중지
110			});
111		} else {
112			$('body').removeClass('overflow-hidden');
113			$(this).attr('title', '사이트맵 열기');
114			$('.stm-gnb .dep1').removeClass('on');
115		}
116	});
117	$('.mgnb .gnb .dep1 a.gnb-tit').on('click', function () {
118		$('.mgnb .gnb .dep1 a.gnb-tit').not($(this)).removeClass('on');
119		$('.mgnb .gnb .dep1 .dep2-wrap').slideUp();
120		var mSubMenu = $(this).next('.dep2-wrap');
121		if (!(mSubMenu.is(":visible"))) {
122			mSubMenu.slideDown();
123			$(this).addClass('on');
124		} else {
125			mSubMenu.slideUp();
126			$(this).removeClass('on');
127		}
128	});
129	$('.mgnb .gnb .dep1 a.gnb-tit').each(function () {
130		if ($(this).next('.dep2-wrap').children().length > 0) {
131			$(this).addClass('arr');
132		}
133	})
134
135
136	//2차, 3차 메뉴 있을때 링크 막기
137	// $('.mgnb-box a.gnb-tit, .mgnb-box a.dep2-tit').on("click", function (e) {
138	// 	e.preventDefault();
139	// });
140
141
142	$('.aside-nav .dep1-tit').on('click', function () {
143		$('.aside-nav .dep1-tit').not($(this)).removeClass('on');
144		$('.aside-nav .dep2').slideUp();
145		var mSubMenu = $(this).next('.dep2');
146		if (!(mSubMenu.is(":visible"))) {
147			mSubMenu.slideDown();
148			$(this).addClass('on');
149		} else {
150			mSubMenu.slideUp();
151			$(this).removeClass('on');
152		}
153	});
154	$('.aside-nav .dep1-tit').each(function () {
155		if ($(this).next('.dep2').length > 0) {
156			$(this).addClass('arr');
157		}
158	})
159
160
161	$('.select-st1 .select-btn').on('click', function (e) {
162		var $btn = $(this);
163		var $list = $btn.siblings('.select-list');
164		if ($list.is(':visible')) {
165			$btn.removeClass('on');
166		} else {
167			$btn.addClass('on');
168		}
169	});
170
171
172
173	const wrap = document.getElementById("wrap");
174	if (wrap && wrap.classList.contains("sub")) {
175		// 서브 좌측 고정
176		gsap.registerPlugin(ScrollTrigger);
177
178		// 3dep용
179		ScrollTrigger.matchMedia({
180
181			"(min-width: 1024px)": function () {
182				const aside = document.querySelector(".layout-aside-1");
183				const main = document.querySelector(".layout-main-1");
184
185				if (!aside || !main) return;
186
187				const pinTrigger = ScrollTrigger.create({
188					trigger: aside,
189					start: "top top",
190					end: () => (main.scrollHeight - aside.offsetHeight) + "px",
191					pin: true,
192					pinSpacing: false,
193				});
194
195				return () => {
196					pinTrigger.kill();
197				};
198			},
199
200			"(max-width: 1023px)": function () {
201				const aside = document.querySelector(".layout-aside-1");
202				if (aside) aside.removeAttribute("style");
203			}
204		});
205
206		// 콘텐츠용
207		ScrollTrigger.matchMedia({
208
209			"(min-width: 1024px)": function () {
210				const aside = document.querySelector(".grid-main .main-aside");
211				const main = document.querySelector(".grid-main .con-body");
212
213				if (!aside || !main) return;
214
215				const pinTrigger = ScrollTrigger.create({
216					trigger: aside,
217					start: "top top",
218					end: () => (main.scrollHeight - aside.offsetHeight) + "px",
219					pin: true,
220					pinSpacing: false,
221				});
222
223				return () => {
224					pinTrigger.kill();
225				};
226			},
227
228			"(max-width: 1023px)": function () {
229				const aside = document.querySelector(".grid-main .main-aside");
230				if (aside) aside.removeAttribute("style");
231			}
232		});
233	}
234
235
236
237
238	//필터 공통
239	$('.filter-wrap').each(function () {
240		const $wrap = $(this);
241
242		$wrap.find('.btn').on('click', function () {
243			const $item = $(this).closest('.item');
244			const $content = $item.find('.cont');
245
246			const isOpen = $item.hasClass('open');
247
248			// 모두 닫기
249			$wrap.find('.item').removeClass('open');
250
251			// 눌린 게 닫힌 상태였으면 열기
252			if (!isOpen) {
253				$item.addClass('open');
254			}
255		});
256	});
257
258
259
260
261	/******************* 맨 위로 이동 *******************/
262	$('.footer .top-btn').on('click', function () {
263		$("html, body").animate({
264			scrollTop: 0
265		}, "slow");
266		return false;
267	});
268
269
270
271
272
273
274
275	// family-site 토글 (네임스페이스 바인딩 + 중복 바인딩 방지)
276	$('.family-btn').off('click.family').on('click.family', function (e) {
277		e.preventDefault();
278		e.stopPropagation();
279		var $currentFamilyList = $(this).next('.family-list');
280
281		if (!$currentFamilyList.is(':visible')) {
282			$(this).addClass('on');
283			$currentFamilyList.stop(true,true).slideDown();
284			$(this).closest('.family-site').siblings('.family-site').find('.family-list').stop(true,true).slide
284Up().prev('.family-btn').removeClass('on');
285		} else {
286			$currentFamilyList.stop(true,true).slideUp();
287			$(this).removeClass('on');
288		}
289	});
290
291	// 문서 바깥 클릭 시 family-list 닫기
292	$(document).off('click.closeFamily').on('click.closeFamily', function () {
293		$('.family-list:visible').stop(true,true).slideUp();
294		$('.family-btn.on').removeClass('on');
295	});
296
297
298
299
300	/******************* 공유하기 *******************/
301	$('.share-wrap .share-btn').on('click', function () {
302		if ($(this).next('.share-layer').is(':visible')) {
303			$(this).next('.share-layer').removeClass('on').attr('aria-expanded', 'false');
304		} else {
305			$(this).next('.share-layer').addClass('on').attr('aria-expanded', 'true');
306		}
307	});
308	$('.share-layer .share-close-btn').on('click', function () {
309		$(this).parents('.share-layer').removeClass('on').attr('aria-expanded', 'false');
310	})
311
312
313
314
315	$('.popup-btn').each(function () {
316		$(this).on('click', function () {
317			const $btn = $(this);
318			const modalId = $btn.data('modal');
319			const $popup = $('.popup-wrap.' + modalId);
320
321			if ($btn.hasClass('zoom-btn')) {
322				// 버튼 내부의 img를 찾음
323				const $imgTarget = $btn.find('img');
324				const imgSrc = $imgTarget.attr('src');
325				const imgAlt = $imgTarget.attr('alt') || '';
326
327				const $popupImg = $popup.find('.img-target img');
328				$popupImg.attr('src', imgSrc).attr('alt', imgAlt);
329
330				if ($("#imgCn").length === 1) {
331					if (imgAlt !== "") {
332						$("#imgCn").show().text(imgAlt);
333					} else {
334						$("#imgCn").hide();
335					}
336				}
337			}
338
339			// 팝업 열기
340			$popup.addClass('active');
341			$('body').addClass('overflow-hidden');
342			if (typeof lenis !== 'undefined' && typeof lenis.stop === 'function') {
343				lenis.stop();
344			}
345		});
346	});
347
348	// 팝업 닫기
349	$('.popup-wrap .popup-close-btn').on('click', function () {
350		$(this).closest('.popup-wrap').removeClass('active');
351		$('body').removeClass('overflow-hidden');
352		if (typeof lenis !== 'undefined' && typeof lenis.start === 'function') {
353			lenis.start();
354		}
355	});
356
357
358
359	/******************* 반응형 테이블 스크롤 안내 *******************/
360	$('.table-scroll-wrap').on('scroll', function () {
361		$(this).find('.table-scroll-event').addClass('hidden');
362	})
363
364
365	/******************* 반응형 테이블 *******************/
366	$('table.bbs-data').not($('.prettyprint').children()).each(function () {
367		var RowSpanExist = $(this).find('td, th').is('[rowspan]'),
368			TheadExist = $(this).find('thead').length;
369		if ((RowSpanExist == false) && (TheadExist != 0)) { //rowspan이 없을 경우만 실행 (rowspan이 있으면 지원불가)
370			$(this).children('table.bbs-data tbody').children('tr').find('th, td').each(function () {
371				var ThisIndex = $(this).index(),
372					TheadText = $(this).parents('table.bbs-data tbody').siblings('thead').find('th').eq(ThisIndex).text();
373				$(this).attr('data-content', TheadText);
374			});
375			$(this).children('table.bbs-data tfoot').children('tr').find('th, td').each(function () {
376				var ThisIndex = $(this).index(),
377					TheadText = $(this).parents('table.bbs-data tfoot').siblings('thead').find('th').eq(ThisIndex).text();
378				$(this).attr('data-content', TheadText);
379			});
380		};
381	});
382
383
384
385	function moreBtnAni() {
386		document.querySelectorAll('.more-btn-ani').forEach(btn => {
387			const em = btn.querySelector('em');
388			const arrows = btn.querySelectorAll('.arrow');
389
390			btn.addEventListener('mouseenter', () => {
391				gsap.to(em, {
392					xPercent: 5,
393					duration: 0.4,
394					ease: 'power2.out'
395				});
396
397				arrows.forEach((arrow, i) => {
398					gsap.to(arrow, {
399						xPercent: 190,
400						duration: 0.4,
401						ease: 'power2.out',
402						delay: i * 0.05
403					});
404				});
405			});
406
407			btn.addEventListener('mouseleave', () => {
408				gsap.to(em, {
409					xPercent: 0,
410					duration: 0.4,
411					ease: 'power2.inOut'
412				});
413				arrows.forEach((arrow, i) => {
414					gsap.to(arrow, {
415						xPercent: 0,
416						duration: 0.4,
417						ease: 'power2.inOut',
418						delay: i * 0.05
419					});
420				});
421			});
422		});
423
424	}
425	moreBtnAni();
426
427
428
429	// ============================
430	// 공통
431	// ============================
432	gsap.registerPlugin(ScrollTrigger);
433
434	// aos 대체 함수
435	function initDataFade() {
436		document.querySelectorAll("[data-fade]").forEach((el) => {
437			const direction = el.dataset.fade || "up";
438			const delay = (el.dataset.fadeDelay || 0) / 1000;
439			const duration = (el.dataset.fadeDuration || 800) / 1000;
440			const once = el.dataset.fadeOnce === "true";
441			const distance = Number(el.dataset.fadeDistance || 100);
442
443			let x = 0,
444				y = 0;
445			if (direction === "up") y = distance;
446			if (direction === "down") y = -distance;
447			if (direction === "left") x = distance;
448			if (direction === "right") x = -distance;
449
450			// ✅ 초기 상태 먼저 설정
451			gsap.set(el, {
452				x: x,
453				y: y,
454				opacity: 0
455			});
456
457			gsap.to(el, { // ✅ from → to로 변경
458				x: 0,
459				y: 0,
460				opacity: 1,
461				duration: duration,
462				delay: delay, // ✅ 이제 delay가 제대로 작동
463				ease: "power3.out",
464				scrollTrigger: {
465					trigger: el,
466					start: "top 80%",
467					toggleActions: once ? "play none none none" : "play none none reset",
468				},
469			});
470		});
471	}
472
473	function splitText() {
474		const target = document.querySelector('.reveal-wrapper .target-text');
475		if (!target) return;
476
477		const text = target.textContent.trim();
478		const chars = text.split('');
479
480		const html = chars.map(char => {
481			if (char === ' ') {
482				return ' ';
483			}
484			return `<span class="word-wrapper"><span class="word"><span class="char">${char}</span></span></span>`;
485		}).join('');
486
487		target.innerHTML = html;
488	}
489
490	function initTextAnimation() {
491		splitText();
492
493		// 초기 상태 설정
494		gsap.set('.char', {
495			y: 100,
496			opacity: 0,
497			rotation: 15
498		});
499
500		gsap.timeline({
501				scrollTrigger: {
502					trigger: '.reveal-wrapper',
503					start: 'top 80%',
504					toggleActions: 'play none none reset',
505					markers: false
506				}
507			})
508			.to('.char', {
509				y: 0,
510				opacity: 1,
511				rotation: 0,
512				duration: 0.8,
513				ease: 'power3.out',
514				stagger: {
515					amount: 0.6,
516					from: 'random'
517				}
518			});
519	}
520
521	function replayAnimation() {
522		gsap.set('.char', {
523			y: 100,
524			opacity: 0,
525			rotation: 15
526		});
527
528		gsap.to('.char', {
529			y: 0,
530			opacity: 1,
531			rotation: 0,
532			duration: 0.8,
533			ease: 'power3.out',
534			stagger: {
535				amount: 0.6,
536				from: 'random'
537			}
538		});
539	}
540
541	// 페이지 로드 시 모든 애니메이션 초기화
542	window.addEventListener('load', function () {
543		initDataFade(); // data-fade 초기화
544		initTextAnimation(); // 텍스트 split 초기화
545	});
546
547	// Floating Menu 기능 (main.html과 동일)
548	function initFloatingMenu() {
549		const $btns = $('.fixed-menu .btn-wrap a');
550		const $list = $('.fixed-list');
551
552		$btns.off('click.fixedMenu').on('click.fixedMenu', function (e) {
553			e.preventDefault();
554			e.stopImmediatePropagation();
555
556			if ($list.is(":visible")) {
557				$list.stop(true, true).slideUp(function(){ $list.css('z-index','-1'); });
558				$btns.removeClass('on');
559			} else {
560				$list.css('z-index','1001').stop(true, true).slideDown();
561				$btns.addClass('on');
562			}
563		});
564
565		// 클릭이 문서 바깥에서 발생하면 닫기
566		$(document).off('click.fixedMenuClose').on('click.fixedMenuClose', function () {
567			if ($list.is(":visible")) {
568				$list.stop(true,true).slideUp(function(){ $list.css('z-index','-1'); });
569				$btns.removeClass('on');
570			}
571		});
572
573		// fixed-menu 내부 클릭은 전파 차단
574		$('.fixed-menu').off('click.fixedMenu').on('click.fixedMenu', function(e){ e.stopPropagation(); });
575	}
576
577	// Floating Menu 초기화
578	$(document).ready(function() {
579		initFloatingMenu();
580	});
581});

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.