잿꽃's posting Garden

자바스크립트로 메뉴 dropdown - slidedown효과 만들기 본문

WEB/JAVASCRIPT

자바스크립트로 메뉴 dropdown - slidedown효과 만들기

잿꽃 2022. 5. 10. 23:21

자바스크립트로 만드는 서브메뉴 slidedown효과

자바스크립트로 메뉴를 만들 때 제이쿼리를 이용하지 않고 dropdown시에 slidedown의 효과를 만들고 싶은데 CSS를 단순히 height값만 조정으로는 잘 되지 않았다. 평소 궁금하던 차에 검색을 해보았다. 이유가 height에 transition이 작동하지 않는다라는 답변을 보았는데 단순히 그런 문제인지 왜 작동하지 않는지 확인해보기로 했다. 이것은 단순히 CSS로 구현했을 때에도 해당되는 내용이다.

 

 

 

0. CSS의 :hover를 이용하여 CSS로만 구현하기

.menu_list .main .sub{
     height: 0;
     overflow: hidden;
     transition: all 0.4s;
}
.menu_list .main:hover .sub{
     height: 150px;
     transition: all 0.4s;
}

사실 메뉴의 작동은 간단하기 때문에 CSS로 구현하는 것이 가장 쉽고 빠르다^^...

코드에 대한 자세한 설명은 2-2 참고

 

 

 

일단 slidedown효과는 제이쿼리로 만들면 아주 간단하게 만들 수 있다.

1. 제이쿼리로 메뉴를 dropdown하고 slidedown효과를 넣는 방법

$('#gnb > li').hover(function(){
   $(this).find('.sub').stop().slideDown();
},function(){
   $(this).find('.sub').stop().slideUp();})

제이쿼리는 다양한 애니메이션을 제공하고 있어 아주 간단한 코드로 만들 수 있다.

 

 

 

만약 자바스크립트로 구현을 해야한다면?

2-1. 자바스크립트로 메뉴를 dropdown하고 slidedown효과를 넣는 방법

코드의 길이나 효율로 보면 CSS로 하지 왜 이 짓을 해야하나 싶지만 하나를 만드는데에는 여러가지 방법이 있으니까ㅎㅎ.......

//메인 메뉴를 선택
const menuhover = document.querySelectorAll('.main__title');
//하위 메뉴를 선택
const subShow = document.querySelectorAll('.sub');
//모든 메인 메뉴에 이벤트 적용
menuhover.forEach(function(item, index){
    item.addEventListener('mouseenter',()=>{
        subShow[index].classList.add('show');
    })
    //메인 메뉴에서 떠날 때
    item.addEventListener('mouseleave',()=>{
        subShow.forEach(function(item,index){
        	//메인 메뉴에서 떠났지만 서브메뉴에 머무를 때
            item.addEventListener('mouseenter',()=>{
                subShow[index].classList.add('show');
            })
            //메인 메뉴에서 떠났고 서브메뉴에 떠날 때
            item.addEventListener('mouseleave',()=>{
                subShow[index].classList.remove('show');
            })
        })
        //서브 메뉴에서 머무르지 않고 메인에서 바로 떠날 때
        if(subShow[index].classList.contains('show')){
            subShow[index].classList.remove('show');
        }
    })
});

복잡해보이지만 간단하게 클래스를 부여하고 삭제하는 코드이다. 자바스크립트로 구현하면 굉장히 길어진다.

 

2-2. CSS에서 height 또는 max-height를 조정한다.

.menu_list .main .sub{
     height: 0; //max-height도 된다.
     overflow: hidden;
     transition: all 0.4s;
}
.menu_list .main .sub.show{
     height: 150px; //max-height도 된다.
     transition: all 0.4s;
}

.sub의 하위에는 li라는 서브메뉴의 타이틀들이 들어가 있고 이것들이 각각의 높이값을 가지고 있어서 .sub의 height를 0으로 지정하여도 변화되지 않는다. 즉, transition이 제대로 작동하지 않는다. 기존의 검색 답변인 'height에 transition이 작동하지 않는다.'라기보다는 하위의 요소에 크기 값이 존재하기 때문이라고 볼 수 있는 것 같다.

방법으로는 overflow: hidden으로 적용해 주는 것이다. hidden의 사이즈가 0에서 150으로 변화되면서 이 변화를 감지하여 작동되게 할 수 있다.

(transition에 all이 아닌 height를 적어도 된다. overflow : hidden값이 높이 값과 동일하다.)

 

 

 

 

3-1. 만약 메뉴가 아닌 다른 요소일 경우 (상위와 하위 관계가 없는 경우)

메뉴의 경우 하위 메뉴의 높이 크기가 있기 때문에 height만으로 변화가 생기지 않는데 만약 보이려는 것들이 단독으로 존재한다면 어떨까 해서 만들어봤다.

const box = document.querySelector('.box');
const boxActive = document.querySelector('.box-active');
boxActive.addEventListener('mouseenter',()=>{
    box.classList.add('show');
})
boxActive.addEventListener('mouseleave',()=>{
    box.classList.remove('show');
})

자바스크립트에서는 간단하게 클래스를 부여하고 삭제하는 코드이다.

 

3-2. CSS에서 height값을 조정한다.

.box-active{
    width: 100px;
    height: 50px;
    background: slateblue;
}
.box{
    width: 200px;
    height: 0px;
    transition: height 0.4s;
    background: slategrey;
}
.box.show{
    height: 100px;
}

상위, 하위가 아닌 독립적인 요소끼리는 문제가 되지 않는다. 어쩌면 당연한 사실일 수도 있다.

물론 코드를 아주 조금만 바꿔 :hover를 이용하여 CSS로만 작성하였을 때도 결국은 같은 코드이기 때문에 동일하다.

 

728x90
Comments