코딩 기록/코딩 소스 [HTML & CSS & JS]

자바스크립트 제이쿼리 header gnb 탑메뉴 예제 3 (PC & 모바일)

kimyang-Sun 2023. 2. 1. 21:39

자바스크립트 (JavaScript)

 

See the Pen 자바스크립트 header gnb 탑메뉴 예제 3 (PC & 모바일) by kimyangsun (@kimyangsun) on CodePen.

https://codepen.io/kimyangsun/pen/YzjJgLL

 

자바스크립트 header gnb 탑메뉴 예제 3 (PC & 모바일)

...

codepen.io

 

자바스크립트 header gnb 탑메뉴 예제 3 (PC & 모바일) 코드펜 소스입니다.

저번에 두번째 예제까지 올리고 나서 생각해보니까 또 다른 자주 쓰이는 방식을 깜빡해서 예제 샘플을 하나 더 만들었습니다 :)

 

예제 1 처럼 2차 메뉴까지 보여주는데 이건 한번에 보여주는게 아닌 각각 해당하는 1차 메뉴에 대한 2차 메뉴만 보여주는 방식입니다.

 

"use strict";

// 헤더 gnb 스크립트
const header = document.querySelector('.header');
const mobileGnb = document.querySelector('.mobile-gnb');
window.addEventListener('DOMContentLoaded', () => {
  initGnb(header);
  initMobileGnb(mobileGnb);
})

// PC
function initGnb(header){
  let gnb = header.querySelector('.header-gnb');
  let gnbMenus = gnb.querySelectorAll('.gnb-depth-1 .depth-1');

  [...gnbMenus].forEach(menu => {
    menu.addEventListener('mouseenter', (event) => {
      gnbOpen(event.target);
    });
    menu.addEventListener('focusin', (event) => {
      gnbOpen(event.target.closest('.depth-1'));
    });

    menu.addEventListener('mouseleave', (event) => {
      gnbClose(event.target);
    });
    menu.addEventListener('focusout', (event) => {
      gnbClose(event.target.closest('.depth-1'));
    });
  });

  function gnbOpen(target){
    let targetItem = target.querySelector('.depth-item');
    let targetMenu = target.querySelector('.gnb-depth-2');
    let targetHeight = targetMenu.getBoundingClientRect().height;
    header.classList.add('open');
    target.classList.add('current');
    targetItem.style.height = `${targetHeight}px`;
  }

  function gnbClose(target){
    let targetItem = target.querySelector('.depth-item');
    header.classList.remove('open');
    target.classList.remove('current');
    targetItem.style.height = '0px';
  }
}

// Mobile
function initMobileGnb(mobileGnb){
  let html = document.querySelector('html');
  let sidebarButton = mobileGnb.querySelector('.sidebar-btn');
  let mobileMenuButtons = mobileGnb.querySelectorAll('.depth-1 a');

  sidebarButton.addEventListener('click', (event) => {
    if (mobileGnb.classList.contains('open')) {
      mobileGnbClose(mobileGnb);
    } else {
      mobileGnbOpen(mobileGnb);
    }
  });

  mobileMenuButtons.forEach(button => {
    button.addEventListener('click', (event) => {
      event.preventDefault();
      let $this = event.target;
      openAccordion($this);
    });
  })

  window.addEventListener('resize', function(){
    if (window.innerWidth > 1024) {
      mobileGnbClose(mobileGnb);
    }
  });

  function mobileGnbOpen(gnb){
    gnb.classList.add('open');
    html.classList.add('not-scroll');
  }

  function mobileGnbClose(gnb){
    gnb.classList.remove('open');
    html.classList.remove('not-scroll');
  }

  // 모바일 메뉴 아코디언
  function openAccordion($this) {
    let target = $this.parentElement;
    let depthTarget = $this.nextElementSibling;
    if (!depthTarget) return;
    let otherLinks = siblings(target);
    let otherItems = otherLinks.map(link => link.querySelector('ul'));

    if (target.classList.contains('open')){
      target.classList.remove('open');
      depthTarget.style.maxHeight = '0px';
    } else {
      otherLinks.forEach(link => link.classList.remove('open'));
      otherItems.forEach(item => item ? item.style.maxHeight = '0px' : '');
      target.classList.add('open');
      depthTarget.style.maxHeight = depthTarget.scrollHeight + 'px';
    }
  }
}

function siblings(element) {
  return [...element.parentElement.children].filter(value => value != element);
}

 

 

자바스크립트 header gnb 탑메뉴 예제 1 (PC & 모바일)

See the Pen header gnb 탑메뉴 예제 1 (자체 커스텀 코드) by kimyangsun (@kimyangsun) on CodePen. https://codepen.io/kimyangsun/pen/BaYKPXm 자바스크립트 header gnb 탑메뉴 예제 1 (PC & 모바일) ... codepen.io 자바스크립트 header

kimyang-sun.tistory.com

 

자바스크립트 header gnb 탑메뉴 예제 2 (PC & 모바일)

See the Pen header gnb 탑메뉴 예제 2 (자체 커스텀 코드) by kimyangsun (@kimyangsun) on CodePen. https://codepen.io/kimyangsun/pen/XWZdPbL 자바스크립트 header gnb 탑메뉴 예제 2 (PC & 모바일) ... codepen.io 자바스크립트 header

kimyang-sun.tistory.com