PageSourceSearch

https://www.safedriving.or.kr/resources/js/common.js

js safedriving.or.kr collected 2026-09-26 04:01:04 UTC 51,138 bytes, 1,462 lines download raw bytes

1/* 모바일 : 전체메뉴 */
2const mobGnb = {
3  target: {
4    header       : "#header",
5    gnbOpen      : "#m-gnb-open",
6    gnbWrap      : ".m-gnb-wrap",
7    gnbIn        : ".m-gnb-wrap .m-gnb-in",
8    gnbBody      : ".m-gnb-wrap .m-gnb-body",
9    gnbMenu      : ".m-gnb-wrap .menu-wrap .mn",
10    gnbMenuHori  : ".m-gnb-wrap .menu-hori",
11    gnbClose     : ".m-gnb-wrap .ico-close",
12    gnbAnchor    : ".m-gnb-menu .submenu-wrap .dl",
13    gnbTopScroll : ".m-gnb-wrap .m-gnb-top-scroll"
14  },
15
16  init: () => {
17    const $mGnbBtn = document.querySelector(mobGnb.target.gnbOpen);
18    const $mGnb = document.querySelector(mobGnb.target.gnbWrap);
19    if (!$mGnb) return;
20
21    const $mGnbCloseBtn = $mGnb.querySelector(mobGnb.target.gnbClose);
22    const $mGnbBody = $mGnb.querySelector(mobGnb.target.gnbBody);
23
24    mobGnb.anchor();
25    mobGnb.accordion(); // ✅ 아코디언 여기서 1번만
26
27    $mGnb.setAttribute("aria-hidden", "true");
28
29    $mGnbBtn.addEventListener("click", mobGnb.open);
30    $mGnbCloseBtn.addEventListener("click", mobGnb.close);
31    $mGnbBody.addEventListener("scroll", mobGnb.anchorScroll);
32  },
33
34  open: () => {
35    const $header = document.querySelector(mobGnb.target.header);
36    const $mGnb = document.querySelector(mobGnb.target.gnbWrap);
37    const $mGnbIn = document.querySelector(mobGnb.target.gnbIn);
38
39    $header.style.zIndex = "1000";
40    $mGnb.setAttribute("aria-hidden", "false");
41    $mGnb.classList.add("is-open");
42    $mGnbIn.setAttribute("tabindex", "0");
43    $mGnbIn.focus();
44    document.body.classList.add("is-m-gnb");
45  },
46
47  close: () => {
48    const $header = document.querySelector(mobGnb.target.header);
49    const $mGnb = document.querySelector(mobGnb.target.gnbWrap);
50    const $mGnbBtn = document.querySelector(mobGnb.target.gnbOpen);
51    const $mGnbIn = document.querySelector(mobGnb.target.gnbIn);
52
53    $mGnb.classList.remove("is-open");
54    $mGnb.classList.add("is-close");
55    $mGnbIn.removeAttribute("tabindex");
56    $mGnb.setAttribute("aria-hidden", "true");
57    document.body.classList.remove("is-m-gnb");
58    $mGnbBtn.focus();
59
60    setTimeout(() => {
61      $mGnb.classList.remove("is-close");
62      $header.style.zIndex = "";
63    }, 500);
64  },
65
66  /* 모바일 GNB 2뎁스 아코디언 */
67  accordion: () => {
68    if (mobGnb._accordionBinded) return;
69    mobGnb._accordionBinded = true;
70
71    document.addEventListener("click", (e) => {
72      const $btn = e.target.closest(".sub-depth-trigger");
73      if (!$btn) return;
74
75      const $mGnb = $btn.closest(".m-gnb-wrap");
76      if (!$mGnb) return;
77
78      const isExpanded = $btn.getAttribute("aria-expanded") === "true";
79      const targetId = $btn.getAttribute("aria-controls");
80      const $subMenu = document.getElementById(targetId);
81      if (!$subMenu) return;
82
83      $btn.setAttribute("aria-expanded", String(!isExpanded));
84      $subMenu.classList.toggle("is-open", !isExpanded);
85    });
86  },
87
88  anchormenuReset: () => {
89    document.querySelectorAll(mobGnb.target.gnbMenu)
90      .forEach(el => el.classList.remove("active"));
91  },
92
93  anchor: () => {
94    const $mGnb = document.querySelector(mobGnb.target.gnbWrap);
95    if (!$mGnb) return;
96
97    const $menus = $mGnb.querySelectorAll(mobGnb.target.gnbMenu);
98    const $anchors = $mGnb.querySelectorAll(mobGnb.target.gnbAnchor);
99
100    if ($menus.length) $menus[0].classList.add("active");
101
102    $anchors.forEach($item => {
103      $item.querySelectorAll(".is-depth4").forEach($btn => {
104        $btn.addEventListener("click", (e) => {
105          const $target = e.target.nextElementSibling;
106          if (!$target) return;
107
108          $target.style.display = "block";
109          requestAnimationFrame(() => $target.classList.add("is-open"));
110        });
111      });
112    });
113  },
114
115 anchorScroll: () => {
116        const $mGnb = document.querySelector(mobGnb.target.gnbWrap);
117        const $mGnbIn = $mGnb.querySelector(mobGnb.target.gnbIn);
118        const $mGnbMenuHori = $mGnb.querySelector(mobGnb.target.gnbMenuHori);
119        const $mGnbBody = $mGnb.querySelector(mobGnb.target.gnbBody);
120        const $mGnbAnchors = $mGnb.querySelectorAll(mobGnb.target.gnbAnchor);
121        const $mGnbTopScroll = $mGnb.querySelector(mobGnb.target.gnbTopScroll);
122        const _scrollTop = $mGnbBody.scrollTop;
123        const _scrollH = $mGnbBody.scrollHeight;
124        const _bodyH = $mGnbBody.clientHeight;
125
126
127        const reversedAnchors = Array.from($mGnbAnchors).reverse();
128
129        reversedAnchors.forEach(($item) => {
130            const _id = $item.getAttribute("id");
131            const $mn = $mGnb.querySelector(`[href="#${_id}"]`);
132            const _offset = $item.offsetTop;
133            const isTargetReached = _scrollTop >= _offset;
134            return;
135            const isAtBottom = (_bodyH + _scrollTop >= _scrollH);
136            if (isTargetReached) {
137                mobGnb.anchormenuReset();
138                $mn.classList.add("active");
139                if($mGnbTopScroll) {
140                    const $mGnbMenuHoriUl = $mGnbMenuHori.querySelector(".ul");
141                    const _offsetLeft = $mn.offsetLeft;
142                    $mGnbBody.addEventListener('scrollend', () => {
143                        $mGnbMenuHoriUl.scrollLeft = _offsetLeft;
144                    });
145                }
146            }
147        });
148
149        //gnb type2
150        if($mGnbTopScroll) {
151            let _lastBodyScrollY = 0;
152            $mGnbBody.addEventListener('scroll', (e) => {
153                const _bodyScrollY =  e.target.scrollTop;
154                if (_bodyScrollY > 0) {
155                    const _mGnbMenuScrollH = $mGnbTopScroll.scrollHeight;
156                    $mGnbTopScroll.style.height = `${_mGnbMenuScrollH}px`;
157                    $mGnbTopScroll.style.transition = "ease-out .4s";
158                    $mGnbIn.classList.add("is-active");
159                } else if (_bodyScrollY < 50 && _bodyScrollY < _lastBodyScrollY) {
160                    $mGnbTopScroll.style.height = "";
161                    $mGnbTopScroll.style.transition = "ease-out .4s .2s";
162                    setTimeout(() => {
163                        $mGnbIn.classList.remove("is-active");
164                    }, 600);
165                }
166                _lastBodyScrollY = _bodyScrollY;
167            });
168        }
169    },
170};
171document.addEventListener("DOMContentLoaded", () => {
172  mobGnb.init();
173});
174
175
176/*** * 웹 gnb * ***/
177const krds_pcGnb = {
178	init() {
179	  const gnbMenu = document.querySelector(".krds-gnb .gnb-menu");
180	  if (!gnbMenu) return;
181
182	  // gnb 속성설정
183	  gnbMenu.setAttribute("aria-label", "메인 메뉴");
184	  //gnbMenu.setAttribute("role", "menubar");
185
186	  // li 요소 role 초기화
187	  gnbMenu.querySelectorAll("li").forEach((li) => li.setAttribute("role", "none"));
188
189	  // backdrop 설정
190	  this.backdrop = document.querySelector(".gnb-backdrop") || this.createBackdrop();
191
192	  // trigger 설정 및 이벤트 등록
193	  const mainTriggers = gnbMenu.querySelectorAll(".gnb-main-trigger");
194	  const subTriggers = gnbMenu.querySelectorAll(".gnb-sub-trigger");
195	  mainTriggers.forEach((mainTrigger) => this.setupMainTrigger(mainTrigger));
196
197	  this.addEvent(mainTriggers, subTriggers);
198	  this.addKeyboardNavigation(mainTriggers);
199	},
200	setupMainTrigger(mainTrigger) {
201	  const toggleWrap = mainTrigger.nextElementSibling;
202	  if (toggleWrap) {
203		//const uniqueIdx = `gnb-main-menu-${Math.random().toString(36).substring(2, 9)}`;
204		const uniqueIdx = `gnb-main-menu-${crypto.randomUUID().replace(/-/g, '').slice(0,7)}`;
205		//mainTrigger.setAttribute("role", "menuitem");
206		mainTrigger.setAttribute("aria-controls", uniqueIdx);
207		mainTrigger.setAttribute("aria-expanded", "false");
208		//mainTrigger.setAttribute("aria-haspopup", "true");
209		toggleWrap.setAttribute("id", uniqueIdx);
210		//toggleWrap.setAttribute("role", "menu");
211
212		const mainList = toggleWrap.querySelector(".gnb-main-list");
213		if (mainList?.getAttribute("data-has-submenu") === "true") {
214		  const subTriggers = mainList.querySelectorAll(".gnb-sub-trigger");
215		  if (subTriggers.length > 0) {
216			subTriggers[0].classList.add("active");
217			subTriggers[0].nextElementSibling?.classList.add("active");
218		  }
219		  subTriggers.forEach((subTrigger) => this.setupSubTrigger(subTrigger));
220		}
221	  }
222	},
223	setupSubTrigger(subTrigger) {
224	  const hasMenu = subTrigger.nextElementSibling;
225	  if (hasMenu) {
226		//const uniqueIdx = `gnb-sub-menu-${Math.random().toString(36).substring(2, 9)}`;
227		const uniqueIdx = `gnb-main-menu-${crypto.randomUUID().replace(/-/g, '').slice(0,7)}`;
228		//subTrigger.setAttribute("role", "menuitem");
229		subTrigger.setAttribute("aria-controls", uniqueIdx);
230		subTrigger.setAttribute("aria-expanded", subTrigger.classList.contains("active")?"true":"false");
231		//subTrigger.setAttribute("aria-haspopup", "true");
232		if(subTrigger.classList.contains("active")){
233		  subTrigger.setAttribute("style", "border-left: solid;");
234		}
235		//hasMenu.setAttribute("role", "menu");
236		hasMenu.setAttribute("id", uniqueIdx);
237	  }
238	},
239	toggleMainMenu(mainTrigger) {
240	  const isActive = mainTrigger.classList.contains("active");
241	  const lang = document.documentElement.lang;
242	  this.menuReset();
243	  if (!isActive && mainTrigger.nextElementSibling) {
244		mainTrigger.setAttribute("aria-expanded", "true");
245		if(lang == 'en'){
246		  mainTrigger.setAttribute("title", "Close Menu");
247		}else{
248		  mainTrigger.setAttribute("title", "메뉴 닫기");
249		}
250		mainTrigger.classList.add("active");
251		mainTrigger.nextElementSibling.classList.add("is-open");
252		this.toggleBackdrop(true);
253		this.scrollbar(true);
254		this.adjustSubMenuHeight(mainTrigger.nextElementSibling.querySelector(".gnb-main-list"));
255		//this.attr('title', '펼치기');
256	  } else {
257		this.close();
258		//this.attr('title', '접기');
259	  }
260	},
261	toggleSubMenu(subTrigger) {
262	  const otherSubTriggers = subTrigger.closest("ul").querySelectorAll(".gnb-sub-trigger");
263	  otherSubTriggers.forEach((trigger) => {
264		trigger.classList.remove("active");
265		trigger.setAttribute("aria-expanded", "false");
266		trigger.nextElementSibling?.classList.remove("active");
267		trigger.removeAttribute("style");
268	  });
269	  subTrigger.classList.add("active");
270	  subTrigger.setAttribute("aria-expanded", "true");
271	  subTrigger.nextElementSibling?.classList.add("active");
272	  subTrigger.setAttribute("style", "border-left: solid;");
273	  this.adjustSubMenuHeight(subTrigger.closest(".gnb-main-list"));
274	},
275	createBackdrop() {
276	  const backdrop = document.createElement("div");
277	  backdrop.classList.add("gnb-backdrop");
278	  backdrop.style.display = "none";
279	  document.body.appendChild(backdrop);
280	  return backdrop;
281	},
282	toggleBackdrop(isOpen) {
283	  this.backdrop.style.display = isOpen ? "block" : "none";
284	  document.body.classList.toggle("is-gnb-web", isOpen);
285	},
286	adjustSubMenuHeight(target) {
287	  const activeSubList = target.querySelector(".gnb-sub-list.active");
288	  const height = activeSubList?.scrollHeight || 0;
289	  target.style.minHeight = `${height}px`;
290	},
291	scrollbar(hasScroll) {
292	  const condition = hasScroll === "open" ? document.body.scrollHeight > window.innerHeight : hasScroll;
293	  document.body.classList.toggle("hasScrollY", condition);
294	},
295	menuReset() {
296	  document.querySelectorAll(".krds-gnb .gnb-main-trigger:not(.is-link)").forEach((mainTrigger) => {
297		mainTrigger.classList.remove("active");
298		mainTrigger.setAttribute("aria-expanded", "false");
299		const lang = document.documentElement.lang;
300		if(lang == 'en'){
301          mainTrigger.setAttribute("title", "Expand Menu");
302        }else{
303          mainTrigger.setAttribute("title", "메뉴 열기");
304        }
305	  });
306	  document.querySelectorAll(".krds-gnb .gnb-toggle-wrap").forEach((toggleWrap) => {
307		toggleWrap.classList.remove("is-open");
308	  });
309	},
310	close() {
311	  this.toggleBackdrop(false);
312	  this.menuReset();
313	  this.scrollbar(false);
314	},
315	addEvent(mainTriggers, subTriggers) {
316	  this.backdrop.addEventListener("click", () => this.close());
317	  window.addEventListener("keyup", (event) => {
318		if (event.code === "Escape" || !event.target.closest(".krds-gnb")) {
319		  this.close();
320		}
321	  });
322	  mainTriggers.forEach((mainTrigger) => {
323		mainTrigger.addEventListener("click", () => this.toggleMainMenu(mainTrigger));
324	  });
325	  subTriggers.forEach((subTrigger) => {
326		subTrigger.addEventListener("click", () => this.toggleSubMenu(subTrigger));
327	  });
328	},
329	addKeyboardNavigation(mainTriggers) {
330	  const focusMenuItem = (element) => {
331		if (element) {
332		  element.focus();
333		}
334	  };
335	  const findFocusableElement = (element, direction) => {
336		const sibling = direction === "next" ? "nextElementSibling" : "previousElementSibling";
337		const parent = element.closest("li")?.[sibling];
338		return parent ? parent.querySelector("[data-trigger]") : null;
339	  };
340	  document.addEventListener("keydown", (event) => {
341		const target = event.target;
342		if (target.getAttribute("data-trigger")) {
343		  switch (event.key) {
344			case "Home":
345			  event.preventDefault();
346			  focusMenuItem(mainTriggers[0]);
347			  break;
348			case "End":
349			  event.preventDefault();
350			  focusMenuItem(mainTriggers[mainTriggers.length - 1]);
351			  break;
352			case "ArrowRight":
353			case "ArrowDown":
354			  event.preventDefault();
355			  const nextElement = findFocusableElement(target, "next");
356			  focusMenuItem(nextElement);
357			  break;
358			case "ArrowLeft":
359			case "ArrowUp":
360			  event.preventDefault();
361			  const previousElement = findFocusableElement(target, "prev");
362			  focusMenuItem(previousElement);
363			  break;
364			default:
365			  break;
366		  }
367		}
368	  });
369	},
370  };
371
372
373/* 공통 : 레이아웃 */
374const comLayout = {
375    target: {
376        headerTop : document.querySelector("#header-top"),
377        header : document.querySelector("#header"),
378        container : "#container",
379        footer : "#footer",
380    },
381
382    init() {
383        this.scroll();
384        this.headerEvent();
385        this.skipNav(); //
386        window.addEventListener('resize', () => {
387            this.headerEvent();
388        });
389    },
390
391    skipNav() {
392        const skipNav = document.querySelector('#skip-nav');
393        const container = document.querySelector('#subContainer') || document.querySelector('#container');
394        const header = document.querySelector('#header');
395
396        if (!skipNav || !container || !header) return;
397
398        skipNav.addEventListener('click', (e) => {
399            e.preventDefault();
400
401            const headerH = header.offsetHeight;
402            const top =
403                container.getBoundingClientRect().top +
404                window.scrollY -
405                headerH;
406
407            window.scrollTo({
408                top,
409                behavior: 'auto'
410            });
411
412            // 포커스 보장 (접근성)
413            container.setAttribute('tabindex', '0');
414            container.focus({ preventScroll: true });
415        });
416    },
417
418    scroll() {
419        let _lastScrollY = 0;
420        window.addEventListener('scroll', () => {
421            const $wrap = document.querySelector("#wrap");
422            const _conOffsetTop = document.querySelector("#container").offsetTop;
423            const _scrollY = window.scrollY;
424
425            if (_scrollY > _conOffsetTop + 50 && _scrollY > _lastScrollY) {
426                $wrap.classList.add("scroll-down");
427                $wrap.classList.remove("scroll-up");
428            } else if (_scrollY > _conOffsetTop + 50 && _scrollY < _lastScrollY) {
429                $wrap.classList.add("scroll-up");
430                $wrap.classList.remove("scroll-down");
431            } else {
432                $wrap.classList.remove("scroll-down", "scroll-up");
433            }
434
435            _lastScrollY = _scrollY;
436        });
437    },
438
439    headerEvent() {
440        const $header = document.querySelector("#header");
441        const _headerH = document.querySelector("#header .header-in").clientHeight;
442        $header.style.height = `${_headerH + 1}px`;
443    }
444};
445
446
447/* 공통 : 패턴 */
448const common = {
449    target: {
450        header : document.querySelector("#header"),
451        container : "#container",
452        footer : "#footer",
453        prefix : "krds",
454    },
455    device: {
456        isMob : 1024,
457    },
458    init: ()=> {
459        common.dropEvent ();
460        common.toggleEvent();
461        common.accordianEvent.init();
462        const $links = document.querySelectorAll("a");
463        $links.forEach($link => {
464            const _href = $link.getAttribute( 'href' );
465            $link.addEventListener("click", (el) => {
466                if(_href === "#") el.preventDefault();
467            });
468        });
469    },
470    dropEvent: () => {
471        const _dropBtns = document.querySelectorAll(`.${common.target.prefix}-drop-wrap .drop-btn`);
472
473        _dropBtns.forEach(($dropBtn) => {
474            const _span = document.createElement("span");
475            const _txt = document.createTextNode("열기");
476            _span.classList.add("sr-only");
477            _span.appendChild(_txt);
478
479            //$dropBtn.appendChild(_span);
480
481            $dropBtn.addEventListener("click", ($el) => {
482                const $menu = $el.target.nextElementSibling;
483                const $srTxt = $el.target.querySelector(".sr-only");
484                const lang = document.documentElement.lang;
485                if($menu.style.display !== "block") {
486                    common.dropClose();
487                    $menu.style.display = "block"
488                    $el.target.classList.add("active");
489
490                    if($(event.target).parent().attr('class') == 'krds-drop-wrap zoom-drop'){
491                       //$srTxt.textContent = "화면크기 닫기";
492                       if(lang == 'en'){
493                            $('#zoom').attr('title', 'Close');
494                       }else{
495                            $('#zoom').attr('title', '접기');
496                       }
497                    }else if($(event.target).parent().attr('class') == 'krds-drop-wrap'){
498                       //$srTxt.textContent = "Language 닫기";
499                       if(lang == 'en'){
500                            $('#language').attr('title', 'Close');
501                       }else{
502                            $('#language').attr('title', '접기');
503                       }
504                    }else{
505                       $srTxt.textContent = "닫기";
506                    }
507                } else {
508                    common.dropClose();
509                    if($(event.target).parent().attr('class') == 'krds-drop-wrap zoom-drop'){
510                       //$srTxt.textContent = "화면크기 열기";
511                       if(lang == 'en'){
512                            $('#zoom').attr('title', 'Expand');
513                       }else{
514                            $('#zoom').attr('title', '열림');
515                       }
516                    }else if($(event.target).parent().attr('class') == 'krds-drop-wrap'){
517                       //$srTxt.textContent = "Language 열기";
518                       if(lang == 'en'){
519                            $('#language').attr('title', 'Expand');
520                       }else{
521                            $('#language').attr('title', '열림');
522                       }
523                    }else{
524                       $srTxt.textContent = "열기";
525                    }
526                }
527            });
528        });
529
530        document.addEventListener("click", ($e) => {
531            if(!$e.target.closest(`.${common.target.prefix}-drop-wrap`)) common.dropClose();
532        });
533    },
534    dropClose: () => {
535        const _dropBtns = document.querySelectorAll(`.${common.target.prefix}-drop-wrap .drop-btn`);
536        const _dropMenus = document.querySelectorAll(`.${common.target.prefix}-drop-wrap .drop-menu`);
537        _dropMenus.forEach(($menu) => {
538            $menu.style.display = "";
539        });
540        _dropBtns.forEach(($btn) => {
541            $btn.classList.remove("active");
542        });
543    },
544    popupEvent: ($id) => {
545        const $clickBtn = document.activeElement;
546        const $header = common.target.header;
547        const $openTarget = document.querySelector($id);
548        const $openTargetType = $openTarget.getAttribute('data-type');
549        const $focusPopupWrap = document.querySelector(`${$id}`);
550        const $focusPopup = document.querySelector(`${$id} .popup`);
551        const $closeBtn = document.querySelector(`${$id} .popup-close`);
552
553        $openTarget.classList.add("is-open");
554
555        document.body.classList.add("scroll-no");
556        common.accEvent.open();
557        if($openTargetType !== 'bottom' && common.target.header !== null) {
558            $header.style.zIndex="1000";
559        }
560
561        if($openTargetType == 'full') {
562            $openTarget.setAttribute("tabindex", 0);
563            $focusPopupWrap.focus();
564        } else {
565            $focusPopup.setAttribute("tabindex", 0);
566            $focusPopup.focus();
567        }
568
569        $closeBtn.addEventListener("click", () => {
570            $openTarget.classList.remove("is-open");
571            $openTarget.classList.add("is-close");
572            $focusPopup.removeAttribute("tabindex");
573            $clickBtn.focus();
574
575            if (common.target.header !== null) $header.style.zIndex="";
576
577            common.accEvent.close();
578            setTimeout(() => {
579                $openTarget.classList.remove("is-close");
580                document.body.classList.remove("scroll-no");
581            }, 600);
582        });
583    },
584    accEvent :  {
585        open : () => {
586            const $container = document.querySelector(common.target.container);
587            const $footer = document.querySelector(common.target.footer);
588            $container.setAttribute("aria-hidden", "true");
589            $footer.setAttribute("aria-hidden", "true");
590        },
591        close: () => {
592            const $container = document.querySelector(common.target.container);
593            const $footer = document.querySelector(common.target.footer);
594            $container.setAttribute("aria-hidden", "false");
595            $footer.setAttribute("aria-hidden", "false");
596        },
597    },
598    toggleEvent : () => {
599        const _toggleBtns = document.querySelectorAll(".toggle-btn");
600        _toggleBtns.forEach(($toggleBtn) => {
601            $toggleBtn.addEventListener("click", ($btnAct) => {
602                const $target = $btnAct.target.closest(".toggle-head");
603                const $targetBody = $target.nextElementSibling;
604                const _targetBodyH = $targetBody.querySelector(".inner").scrollHeight;
605                const $srEl = $btnAct.target.querySelector(".sr-only");
606
607                if(!$target.classList.contains("active")) {
608                    $srEl.innerText = '닫힘';
609                    $target.classList.add("active");
610                    $targetBody.classList.add("active");
611                    $targetBody.style.height = `${_targetBodyH}px`;
612                    window.addEventListener("resize", () => {
613                        if($targetBody.classList.contains("active")) {
614                            const _targetBodyH = $targetBody.querySelector(".inner").scrollHeight;
615                            $targetBody.style.height = `${_targetBodyH }px`;
616                        }
617                    });
618                } else {
619                    $srEl.innerText = '열림';
620                    $target.classList.remove("active");
621                    $targetBody.classList.remove("active");
622                    $targetBody.style.height = '';
623                }
624
625            })
626        });
627    },
628    accordianEvent : {
629        init: () => {
630            const _accordians = document.querySelectorAll(".acco-list");
631            _accordians.forEach(($parent) => {
632                const _accoDataAct = $parent.getAttribute("data-action");
633                const _accoAct = _accoDataAct !== null;
634                const _lis = $parent.querySelectorAll(".li");
635                const _list = [..._lis];
636                _list.forEach(($e) => {
637                    const $item = $e.closest(".li");
638                    const $itemToggle = $e.querySelector(".acco-btn");
639                    //const $itemSr = $item.querySelector(".acco-btn .sr-only");
640                    const $itemBody = $e.querySelector(".acco-body");
641
642                    if($e.classList.contains("active")) common.accordianEvent.open($item);
643                    if($parent.classList.contains("is-open")) {
644                        common.accordianEvent.open($item);
645                    } else {
646                        $itemBody.style.display = 'none';
647                        //$itemSr.textContent = "펼침";
648                    }
649
650                    $itemToggle.addEventListener("click", ($el) => {
651                        const $menu = $el.target.closest(".li");
652
653                        (!$menu.classList.contains("active")) ? common.accordianEvent.open($menu) : common.accordianEvent.close($menu);
654                        if(_accoAct) common.accordianEvent.reset(_list, $menu);
655                    });
656                });
657            });
658        },
659        open : ($item) => {
660            //const $accoSr = $item.querySelector(".acco-btn .sr-only");
661            const $accoBody = $item.querySelector(".acco-body");
662
663            $item.classList.add("active");
664            $accoBody.style.display = 'block';
665            //$accoSr.textContent = "접기";
666
667            const _accoBodyH = $item.querySelector(".acco-in").scrollHeight;
668            $accoBody.style.height = `${_accoBodyH+1}px`;
669            setTimeout(() => {
670                $accoBody.style.display = 'block';
671            },0);
672
673        },
674        close : ($item) => {
675            //const $accoSr = $item.querySelector(".acco-btn .sr-only");
676            const $accoBody = $item.querySelector(".acco-body");
677
678            //$accoSr.textContent = "펼침";
679            $accoBody.style.height = '';
680            $accoBody.style.overflow = '';
681            $item.classList.remove("active");
682            setTimeout(() => {
683                $accoBody.style.display = 'none';
684            }, 400);
685        },
686        reset : (_list, $menu) => {
687            _list.forEach(($e) => {
688                const $target = $e;
689                //const $accoSr = $target.querySelector(".acco-btn .sr-only");
690                const $accoBody = $target.querySelector(".acco-body");
691                if(_list.indexOf($menu) !== _list.indexOf($target)) {
692                    $target.classList.remove("active");
693                    //$accoSr.textContent = "펼침";
694                    $accoBody.style.height = '';
695                    setTimeout(() => {
696                        $accoBody.style.display = 'none';
697                    }, 400);
698                }
699            });
700        },
701    },
702}
703
704//띠배너 스크롤 시 class 추가
705function lineBnScroll() {
706    const $bn = document.querySelector('#header-top');
707    const $bnHeight = $bn.offsetHeight;
708    const $body = document.querySelector("body");
709    const scrollY = window.scrollY;
710    if ($bn) {
711        $body.classList.add('bn-hidden');
712        if (scrollY <= $bnHeight) {
713            $body.classList.remove('bn-hidden');
714        }
715    }
716}
717
718window.addEventListener("DOMContentLoaded", () => {
719    if(comLayout.target.header !== null) {
720        setTimeout(() => {
721            mobGnb.init();
722            comLayout.init();
723			krds_pcGnb.init();
724        }, 100);
725    }
726});
727
728window.addEventListener("load", () => {
729    setTimeout(() => {
730        common.init();
731    }, 100);
732
733    if (comLayout.target.headerTop !== null) {
734        setTimeout(() => {
735            lineBnScroll();
736        }, 200);
737    }
738});
739
740window.addEventListener('scroll', () => {
741    if (comLayout.target.headerTop !== null) {
742        setTimeout(() => {
743            lineBnScroll();
744        }, 200);
745    }
746});
747
748
749/* ** 윈도우 사이즈 체크 (반응형) ** */
750let winSize;
751function winSizeSet() {
752	const brekpoint = 1024;
753	if (window.innerWidth >= brekpoint) {
754		winSize = 'pc';
755	}
756	else {
757		winSize = 'mob';
758	}
759}
760
761/* layer tab */
762function layerTab() {
763	const layerTabArea = document.querySelectorAll('.tab-area.layer');
764
765	/* 탭 접근성 텍스트 세팅 */
766	const tabAccText = document.createTextNode(' 선택됨');
767	const tabAccTag = document.createElement('i');
768	tabAccTag.setAttribute('class', 'sr-only created');
769	tabAccTag.appendChild(tabAccText);
770
771	layerTabArea.forEach(e => {
772		const layerTabEle = e.querySelectorAll('.tab > ul > li');
773		const tabPanel = e.querySelectorAll('.tab-conts');
774
775		function tab() {
776            layerTabEle.forEach(ele => {
777                const control = ele.getAttribute('aria-controls');
778                const selectedTabPanel = document.getElementById(control);
779
780                if (ele.classList.contains('active')) {
781                    const srLength = ele.getElementsByClassName('sr-only created').length;
782                    if(srLength == '0')
783                    {
784                        //선택됨 텍스트 추가
785                        ele.querySelector('button').append(tabAccTag);
786                    }
787                }
788
789                ele.addEventListener('click', () => {
790                    const srLength = ele.getElementsByClassName('sr-only created').length;
791                    layerTabInitial(); //레이어탭 초기화
792                    ele.classList.add('active');
793                    if(srLength == '0')
794                    {
795                        ele.querySelector('button').append(tabAccTag); //선택됨 텍스트 추가
796                    }
797                    ele.setAttribute('aria-selected', 'true');
798                    if(selectedTabPanel != null){
799                        selectedTabPanel.classList.add('active');
800                    }
801                });
802            });
803        }
804
805		//레이어탭 초기화
806		function layerTabInitial() {
807			layerTabEle.forEach(ele => {
808				ele.classList.remove('active');
809				ele.setAttribute('aria-selected', 'false');
810				//ele.removeAttribute('style');
811				if (ele.classList.contains('active')) {
812                    const text = ele.querySelector('.sr-only.created');
813                    //ele.querySelector('button').removeChild(text);
814                }
815
816			});
817			tabPanel.forEach(ele => {
818				ele.classList.remove('active');
819				//ele.removeAttribute('style');
820			})
821		}
822		tab();
823	});
824}
825
826
827/*** * accordion * ***/
828const $accordionBtn = document.querySelectorAll('.btn-accordion');
829const kds_accordion = {
830	init: () => {
831		kds_accordion.expand();
832	},
833	expand: () => {
834		$accordionBtn.forEach(e => {
835			const $wrapper = e.closest('.accordion');
836			const $wrapAll = $wrapper.querySelectorAll('.accordion-item');
837			const $wrap = e.closest('.accordion-item');
838
839			e.addEventListener('click', () => {
840				if (!$wrap.classList.contains('active')) {
841					$wrapAll.forEach(ele => {
842						ele.classList.remove('active');
843						ele.querySelector('.btn-accordion').classList.remove('active');
844					});
845
846					$wrap.classList.add('active');
847					e.classList.add('active');
848				}
849				else {
850					$wrap.classList.remove('active');
851					e.classList.remove('active');
852				}
853			});
854
855		});
856	},
857}
858
859/*
860const $modalTrigger = document.querySelectorAll('.open-modal');
861const $modalCloseTrigger = document.querySelectorAll('.close-modal');
862const $kds_body = document.querySelector('body');
863const kds_modal = {
864	init: () => {
865		kds_modal.open();
866		kds_modal.close();
867	},
868	open: () => {
869		$modalTrigger.forEach(e => {
870			e.addEventListener('click', ele => {
871				const id = e.getAttribute('data-target');
872
873				e.classList.add('modal-opened');
874				e.setAttribute('tabindex', '-1');
875
876				kds_modal.modalOpen(id);
877				ele.preventDefault();
878			});
879		});
880	},
881	modalOpen: (id) => {
882		const $idVal = document.getElementById(id);
883		const $dialog = $idVal.querySelector('.modal-content');
884		const $modalBack = $idVal.querySelector('.modal-back');
885		const $modalOpened = document.querySelectorAll('.modal.in:not(.sample)');
886		const $modalOpenedLen = $modalOpened.length + 1;
887		$kds_body.classList.add('scroll-no');
888		$idVal.setAttribute('aria-hidden', 'false');
889		$modalBack.classList.add('in');
890		$idVal.classList.add('shown');
891		setTimeout(() => {
892			$idVal.classList.add('in');
893		},150);
894
895		//열린 팝업창 포커스
896		$dialog.setAttribute('tabindex', '0');
897
898		//모달 여러개 열린경우 마지막 열린 모달 z-index높게
899		if ($modalOpenedLen > 1){
900			const openedLen = $modalOpenedLen;
901			const zIndexNew = 1010 + openedLen;
902			$idVal.setAttribute('style', 'z-index: ' + zIndexNew);
903		}
904
905		//레이어 진입 시 포커스
906		setTimeout(() => {
907			$dialog.focus();
908		},350);
909	},
910	close: () => {
911		$modalCloseTrigger.forEach(e => {
912			e.addEventListener('click', ele => {
913				const id = e.closest('.modal').getAttribute('id');
914				kds_modal.modalClose(id);
915			});
916			e.addEventListener('keydown', ele => { //닫기버튼에서 탭 키 누르면 모달 내 첫번쨰 포커스로 키보드 이동
917				if (e.classList.contains('btn-close')) {
918					const keyCode = ele.keyCode || ele.which;
919					if (!ele.shiftKey && keyCode == 9) {
920						e.closest('.modal-content').focus();// 첫번째 링크로 이동
921						ele.preventDefault();
922					}
923				}
924			});
925		});
926	},
927	modalClose: (id) => {
928		const $idVal = document.getElementById(id);
929		const $dialog = $idVal.querySelector('.modal-content');
930		const $modalOpened = document.querySelectorAll('.modal.in:not(.sample)');
931		const $modalOpenedLen = $modalOpened.length;
932		if ($modalOpenedLen < 2) {
933			$kds_body.classList.remove('scroll-no');
934		}
935
936		$idVal.setAttribute('aria-hidden', 'true');
937		$idVal.classList.remove('in');
938
939		$dialog.removeAttribute('tabindex');
940
941		setTimeout(() => {
942			$idVal.classList.remove('shown');
943		},150);
944
945		//모달 창 연 버튼에 class 삭제 및 tabindex 0로 조정 (포커스 영역 수정)
946		const $triggerBtn = document.querySelector('.modal-opened');
947		if ($triggerBtn != null) {
948			$triggerBtn.focus();
949			$triggerBtn.setAttribute('tabindex', '0');
950			$triggerBtn.classList.remove('modal-opened');
951		}
952	},
953}
954*/
955/*** * tooltip * ***/
956const krds_tooltip = {
957    init: ()=> {
958        krds_tooltip.tooltipEvent();
959    },
960    tooltipEvent: () => {
961        const _toolBtns = document.querySelectorAll(".krds-tooltip-wrap .tool-btn");
962
963        _toolBtns.forEach(($toolBtn) => {
964            const _span = document.createElement("span");
965            const _txt = document.createTextNode("열기");
966
967            _span.classList.add("sr-only");
968            _span.appendChild(_txt);
969
970            $toolBtn.innerHTML="";
971            $toolBtn.appendChild(_span);
972
973            $toolBtn.addEventListener("click", ($el) => {
974                const $parent = $toolBtn.closest(".krds-tooltip-wrap");
975                const $closeBtn = $parent.querySelector(".tool-close");
976                const $cnt = $parent.querySelector(".tool-in");
977                const $srTxt = $el.target.querySelector(".sr-only");
978                if($cnt.style.display !== "block") {
979                    $cnt.style.display = "block";
980                    $cnt.setAttribute("tabindex", 0);
981                    $srTxt.textContent = "닫기";
982                    krds_tooltip.tooltipResize($parent, $cnt);
983                }
984                $closeBtn.addEventListener("click", () => {
985                    $srTxt.textContent = "열기";
986                    $cnt.style.display = "";
987                    $cnt.removeAttribute("tabindex");
988                    $toolBtn.focus();
989                    krds_tooltip.tooltipResize($parent, $cnt);
990                });
991
992                window.addEventListener("resize", () => {
993                    krds_tooltip.tooltipResize($parent, $cnt);
994                });
995            });
996        });
997    },
998    tooltipResize: ($parent, $cnt) => {
999        if (winSize === 'mob') {
1000            krds_tooltip.tooltipMob($parent, $cnt);
1001        } else {
1002            krds_tooltip.tooltipPc($cnt);
1003        }
1004        window.addEventListener('resize', () => {
1005            if (winSize === 'mob') {
1006                krds_tooltip.tooltipMob($cnt);
1007            } else {
1008                krds_tooltip.tooltipPc($cnt);
1009            }
1010        });
1011    },
1012    tooltipMob: ($parent, $cnt) => {
1013        const _offsetL = $parent.offsetLeft - 16;
1014        const _width = document.body.clientWidth;
1015        const _offsetR = _width - ($parent.clientWidth + _offsetL) - 32;
1016        if ($cnt) {
1017            $cnt.style.left = `-${_offsetL}px`;
1018            $cnt.style.right = `-${_offsetR}px`;
1019        }
1020    },
1021    tooltipPc: ($cnt) => {
1022        $cnt.style.left = '';
1023        $cnt.style.right = '';
1024    },
1025}
1026
1027/* ** 도움말 ** */
1028const helperArea = document.querySelectorAll('.helper-area');
1029const helperBox = {
1030	init: () => {
1031		if (helperArea.length > 0) {  //해당 클래스 존재할떄만 실행
1032			setTimeout(() => {
1033				helperBox.paddingSet();
1034			},50);
1035			setTimeout(() => {
1036				helperBox.heightSet();
1037			},100);
1038		}
1039	},
1040	paddingSet: () => { //영역 세팅
1041		const bnH = document.querySelector('#header-top').offsetHeight;
1042		const headerH = document.querySelector('#header').offsetHeight;
1043
1044		const defaultPadding = bnH + headerH;
1045		const bnHiddgnPadding = headerH;
1046
1047		const $wrap = document.querySelector('#wrap');
1048		const $expandBtn = document.querySelector('.btn-helper.expand');
1049		const $expandBox = document.querySelector('.helper-wrap');
1050
1051		const $collapseBtn = document.querySelector('.btn-helper.fold');
1052		if (document.body.classList.contains('bn-hidden')) { //top banner 안보임
1053			if ($wrap.classList.contains('scroll-down')) { //header영역 안보임
1054				$expandBtn.style.marginTop = '0';
1055				if (winSize == 'pc') {
1056					$expandBox.style.paddingTop = '0';
1057					$collapseBtn.style.marginTop = '0';
1058				} else {
1059					$expandBox.removeAttribute('style');
1060					$collapseBtn.removeAttribute('style');
1061				}
1062			} else { //header영역 보임
1063				$expandBtn.style.marginTop = bnHiddgnPadding + 'px';
1064				if (winSize == 'pc') {
1065					$expandBox.style.paddingTop = bnHiddgnPadding + 'px';
1066					$collapseBtn.style.marginTop = bnHiddgnPadding + 'px';
1067				} else {
1068					$expandBox.style.paddingTop = '0';
1069					$collapseBtn.removeAttribute('style');
1070				}
1071			}
1072		} else { //top banner 보임
1073			$expandBtn.style.marginTop = defaultPadding + 'px';
1074			if (winSize == 'pc') {
1075				$expandBox.style.paddingTop = defaultPadding + 'px';
1076				$collapseBtn.style.marginTop = defaultPadding + 'px';
1077			} else {
1078				$expandBox.removeAttribute('style');
1079				$collapseBtn.removeAttribute('style');
1080			}
1081		}
1082
1083	},
1084	trigger: () => { //도움말열기 버튼에 추가한 class 삭제
1085		const btnExec = document.querySelectorAll('.btn-help-exec');
1086		if (helperArea.length > 0) {
1087			btnExec.forEach(e => {
1088				e.classList.remove('btn-help-clicked');
1089			});
1090		}
1091	},
1092	expand: () => { //도움말버튼 클릭 시 실행
1093		const btnExec = document.querySelectorAll('.btn-help-exec');
1094		const target = document.querySelector('.helper-wrap');
1095		if (helperArea.length > 0) {
1096			btnExec.forEach(e => {
1097				e.addEventListener('click', () => {
1098					helperBox.open();
1099					helperBox.trigger();
1100					e.classList.add('btn-help-clicked');
1101					setTimeout(() => {
1102						target.focus();
1103					}, 50);
1104				});
1105			});
1106		}
1107
1108	},
1109	collapse: () => { //도움말 접어두기 버튼 클릭 시 실행
1110		const btn = document.querySelector('.btn-helper.fold');
1111
1112		if (helperArea.length > 0) {
1113			btn.addEventListener('click', () => {
1114				if (winSize == 'mob') {
1115					document.body.classList.remove('scroll-no');
1116				}
1117				helperBox.close();
1118			});
1119		}
1120	},
1121	open: () => { //도움말 열기
1122		if (helperArea.length > 0) {  //해당 클래스 존재할떄만 실행
1123			const target = document.querySelector('.helper-wrap');
1124			const inner = document.querySelector('#container > .inner');
1125			const $header = document.querySelector("#header .head-body > .inner");
1126			const $container = document.querySelector("#container");
1127			const _width = document.body.clientWidth;
1128			if (winSize == 'mob') {
1129				document.body.classList.add('scroll-no');
1130			}
1131			target.setAttribute('aria-expanded', 'true');
1132			target.setAttribute('tabindex', '0');
1133			document.querySelector('.helper-area').classList.add('expand');
1134
1135			if (inner.classList.contains('flexible')) { // 화면 사이즈 줄어들면 영역도 줄어들게
1136				inner.classList.remove('folded');
1137				$container.classList.remove('help-close');
1138				$container.classList.add("help-open");
1139				const _headerL = $header.offsetLeft;
1140				if( _width > 1024 && _width < 1900  ){
1141					$container.classList.remove("help-open");
1142					$container.classList.add("help-open");
1143					$container.style.paddingRight="";
1144					$container.style.paddingLeft=`${_headerL+26}px`;
1145				}
1146
1147				helperBox.resize($header, $container);
1148			}
1149		}
1150	},
1151	close: () => { //도움말 접기
1152		const $header = document.querySelector("#header .head-body > .inner");
1153		const $container = document.querySelector('#container');
1154		const target = document.querySelector('.helper-wrap');
1155		const inner = document.querySelector('#container > .inner');
1156		const trigger = document.querySelectorAll('.btn-help-clicked');
1157		const _width = document.body.clientWidth;
1158		target.setAttribute('aria-expanded', 'false');
1159		target.removeAttribute('tabindex');
1160		document.querySelector('.helper-area').classList.remove('expand');
1161
1162		if (trigger.length > 0) { //버튼 클릭으로 도움말 펼친경우 클릭한 버튼으로 포커스
1163			trigger[0].focus();
1164		}
1165
1166		if (inner.classList.contains('flexible')) { // 도움말 닫히면 컨텐츠 영역 늘리기
1167			inner.classList.add('folded');
1168			$container.classList.add("help-close");
1169			$container.classList.remove("help-open");
1170			$container.style.paddingLeft=``;
1171			if ($container.classList.contains('help-close')) {
1172				$container.style.paddingLight=``;
1173				$container.style.paddingRight=``;
1174			} else if (_width > 1900 || _width <= 1024 ) {
1175				$container.classList.remove("help-open");
1176				$container.classList.remove("help-close");
1177			}
1178			helperBox.resize($header, $container);
1179		}
1180	},
1181	resize: ($header, $container) => {
1182		window.addEventListener("resize", () => {
1183			const _headerL = $header.offsetLeft;
1184			const _width = document.body.clientWidth;
1185			if ( _width > 1024 && _width < 1900) {
1186				$container.style.paddingRight="";
1187				if($container.classList.contains("help-open")) {
1188					$container.style.paddingLeft=`${_headerL+26}px`;
1189				}else {
1190					$container.style.paddingLeft=``;
1191				}
1192			} else if ( _width <= 1024 ) {
1193				$container.style.paddingLeft="";
1194				$container.style.paddingRight="";
1195			} else {
1196				$container.style.paddingLeft= "";
1197			}
1198		});
1199	},
1200	heightSet: () => {
1201		const $helperArea = document.querySelector('.helper-area');
1202		const $expandBox = document.querySelector('.helper-wrap');
1203		const $contsArea = document.querySelector('.helper-conts-area');
1204		const helperTitH = document.querySelector('.helper-tit').offsetHeight;
1205
1206		const contsPt = parseInt(getComputedStyle($expandBox).paddingTop);
1207		const contsAreaH = window.innerHeight - helperTitH - contsPt;
1208
1209		$contsArea.style.height = contsAreaH + 'px';
1210
1211		if (winSize == 'mob') {
1212			if ($helperArea.classList.contains('expand')) {
1213				document.body.classList.add('scroll-no');
1214			}
1215		} else {
1216			document.body.classList.remove('scroll-no');
1217		}
1218
1219	}
1220}
1221
1222/* ** 영역 높이 확장 축소 ** */
1223function collapseBox() {
1224	const box = document.querySelectorAll('.conts-expand-area');
1225	box.forEach(e => {
1226		const btn = e.querySelector('.btn-conts-expand');
1227		if (btn != null) {
1228			btn.addEventListener('click', () => {
1229				e.classList.toggle('active');
1230			});
1231		}
1232	});
1233}
1234
1235/* ** 박스형 체크박스 상태에 따른 디자인 변경 ** */
1236function chkBox() {
1237	const box = document.querySelectorAll('.chk-group-wrap');
1238	box.forEach(e => {
1239		const boxList = e.querySelectorAll('li');
1240		boxList.forEach(ele => {
1241			ele.removeAttribute('class');
1242			const thisList = ele.closest('li');
1243			const checkbox = ele.querySelector('input[type=checkbox]');
1244			if (checkbox != null) {
1245				const is_disabled = checkbox.disabled;
1246				let is_checked = checkbox.checked;
1247
1248				if (is_disabled == true) {
1249					thisList.classList.add('disabled');
1250				}
1251				else {
1252					if (is_checked == true) {
1253						thisList.classList.add('checked');
1254					}
1255				}
1256
1257				checkbox.addEventListener('click', () => {
1258					if (is_checked == true) {
1259						thisList.classList.remove('checked');
1260						is_checked = false;
1261					} else {
1262						thisList.classList.add('checked');
1263						is_checked = true;
1264					}
1265				});
1266			}
1267
1268			const rdo = ele.querySelector('input[type=radio]');
1269			if (rdo != null) {
1270				const is_disabled = rdo.disabled;
1271				let is_checked = rdo.checked;
1272
1273				if (is_disabled == true) {
1274					thisList.classList.add('disabled');
1275				}
1276				else {
1277					if (is_checked == true) {
1278						thisList.classList.add('checked');
1279					}
1280				}
1281
1282				rdo.addEventListener('click', (e) => {
1283					const rdoGroup = rdo.closest('.chk-group-wrap');
1284					const rdoLi = rdoGroup.querySelectorAll('li');
1285					let is_checked2 = e.checked;
1286					rdoLi.forEach(ele => {
1287						ele.classList.remove('checked');
1288						is_checked2 = false;
1289					});
1290					if (is_checked2 == true) {
1291						thisList.classList.remove('checked');
1292						is_checked2 = false;
1293					} else {
1294						thisList.classList.add('checked');
1295						is_checked2 = true;
1296					}
1297				});
1298			}
1299
1300		});
1301	});
1302}
1303
1304
1305/* ** 스크롤 값 체크 ** */
1306let scrollY = window.scrollY;
1307let scrollH = document.body.scrollHeight;
1308function scrollVal() {
1309	scrollY = window.scrollY;
1310	scrollH = document.body.scrollHeight;
1311}
1312
1313/* ** 스크롤 네비게이션 ** */
1314const winHeight = window.innerHeight;
1315const quickIndicators = document.querySelectorAll('.quick-list');
1316
1317const quickNav = {
1318	init: () => {
1319		if (quickIndicators.length > 0) { //해당 클래스 존재할떄만 실행
1320			quickNav.linkNav();
1321		}
1322	},
1323	reset: () => { //초기화
1324		quickIndicators.forEach(e => {
1325			const locationList = e.querySelectorAll('a');
1326			locationList.forEach(ele => {
1327				ele.classList.remove('active');
1328			});
1329		});
1330	},
1331	linkNav: () => { //퀵 네비게이션 클릭 시 스크롤 이동
1332		quickIndicators.forEach(e => {
1333			const locationList = e.querySelectorAll('a');
1334			locationList.forEach(ele => {
1335				const target = document.querySelector(ele.getAttribute('href'));
1336				const offsetY = target.getBoundingClientRect().top + scrollY;
1337
1338				ele.addEventListener('click', (ev) => {
1339					ev.preventDefault();
1340
1341					window.scrollTo({
1342						left: 0,
1343						top: offsetY,
1344						behavior: 'smooth',
1345					});
1346				});
1347			});
1348		});
1349	},
1350	navHighlight: () => { //페이지 스크롤 시 퀵 네비게이션 해당메뉴 active
1351		if (quickIndicators.length > 0) {
1352			const sectionArea = document.querySelectorAll('.section-link');
1353			const topHeight = Math.ceil(winHeight / 5);
1354			const firstSecTop = document.querySelectorAll('.scroll-check .section-link')[0].offsetTop;
1355			sectionArea.forEach(current => {
1356				const sectionHeight = current.offsetHeight;
1357				const sectionTop = current.offsetTop - topHeight;
1358				const sectionId = current.getAttribute("id");
1359				if (scrollY <= firstSecTop) { //스크롤이 첫번째 섹션보다 위에 있으면 맨 위 네비 active
1360					document.querySelector(".conts-area > .quick-nav-area .quick-list li:first-of-type a").classList.add("active");
1361				}
1362				else if (scrollY + winHeight >= scrollH) { //스크롤이 맨 하단에 있으면 맨 아래 네비 active
1363					quickNav.reset();
1364					document.querySelector(".conts-area > .quick-nav-area .quick-list li:last-of-type a").classList.add("active");
1365				}
1366				else {
1367					if (scrollY > sectionTop && scrollY <= sectionTop + sectionHeight) { //스크롤이 해당 섹션
1368						document.querySelector(".conts-area > .quick-nav-area a[href*=" + sectionId + "]").classList.add("active");
1369					} else {
1370						document.querySelector(".conts-area > .quick-nav-area a[href*=" + sectionId + "]").classList.remove("active");
1371					}
1372				}
1373			});
1374		}
1375	},
1376}
1377
1378/* ** 스킵네비게이션 클릭 시 scroll 맨 위로 ** */
1379function goTop() {
1380	const $skip = document.querySelector('.go-top');
1381	$skip.addEventListener('click', () => {
1382		setTimeout(() => {
1383			window.scrollTo({
1384				left: 0,
1385				top: 0,
1386				behavior: 'smooth',
1387			});
1388
1389            const logoLink= document.querySelector('.logo a');
1390
1391
1392            if(logoLink) {
1393                 logoLink.setAttribute('tabindex', '-1');
1394
1395                 logoLink.addEventListener('focus', ()  => {
1396                    logoLink.style.outline = "2px solid #000";
1397                 }, {once: false});
1398
1399                 logoLink.addEventListener('blur', ()  => {
1400                    logoLink.style.outline = "none";
1401                 }, {once: false});
1402                 logoLink.focus();
1403            }
1404		}, 200);
1405	});
1406}
1407
1408window.addEventListener("DOMContentLoaded", () => {
1409	layerTab();
1410	kds_accordion.init();
1411    //kds_modal.init();
1412    krds_tooltip.init();
1413
1414	/* ** 윈도우 사이즈 체크 (반응형) ** */
1415	winSizeSet();
1416
1417	/* ** 영역 높이 확장 축소 ** */
1418	collapseBox();
1419
1420	/* ** 박스형 체크박스 상태에 따른 디자인 변경 ** */
1421	chkBox();
1422
1423	/* ** 스크롤 네비게이션 ** */
1424	quickNav.init();
1425
1426	/* ** 스킵네비게이션 클릭 시 scroll 맨 위로 ** */
1427	if(document.querySelector('.go-top') !== null) goTop();
1428
1429	setTimeout(() => { //gnb footer 등 include영역으로 로딩시간이 필요한경우 settimeout에 넣어줌 (배포시 삭제필요)
1430		/* ** 도움말 ** */
1431		helperBox.init();
1432		if (winSize == 'pc') {
1433			helperBox.open();
1434		}
1435
1436		//클릭이벤트는 로드시에만 실행시키기
1437		helperBox.expand();
1438		helperBox.collapse();
1439	}, 200);
1440});
1441
1442
1443window.addEventListener('scroll', () => {
1444	/* ** 스크롤 값 체크 ** */
1445	scrollVal();
1446
1447	/* ** 스크롤 네비게이션 ** */
1448	//quickNav.navHighlight();
1449
1450	setTimeout(() => { //gnb footer 등 include영역으로 로딩시간이 필요한경우 settimeout에 넣어줌 (배포시 삭제필요)
1451		/* ** 도움말 ** */
1452		helperBox.init();
1453	}, 200);
1454});
1455
1456window.addEventListener('resize', () => {
1457	/* ** 윈도우 사이즈 체크 (반응형) ** */
1458	winSizeSet();
1459
1460	/* ** 도움말 ** */
1461	helperBox.init();
1462});

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.