🤹🏻‍♀️ Javascript

'이벤트 객체'를 통해서 메뉴 활성화 버튼 실습

ji-hyun 2020. 5. 6. 01:48

e <-------  이벤트 객체에 대해서 알아보겠습니다.

 

 

< '이벤트 객체' 란? >

  • '이벤트 발생시 전달되는 정보'라는 뜻으로, 만약 '클릭'이라는 이벤트를 발생했을 시, 이벤트 객체는 해당 이벤트에 대한 상세한 정보를 담고 있다. 예) 마우스 위치, 마우스 버튼의 상태, 옵션키(연관된 ctrl, Alt, Shift 키) 등
  • 이벤트 핸들러에 전달되는 이벤트 정보를 담고 있다.
  • 이벤트 리스너 함수에 넘겨지는 인수(매개변수) 이다.

 

 

 

 

 

예제를 통해서 설명을 덧붙이겠습니다.

먼저 html과 css는 다음과 같습니다.

 

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>자바스크립트 기초</title>
        <style>
            body { font-size: 3rem;}
            h1 { background-color: #fff000;}
            .menu {
                display: flex;   
                border: 1px solid yellow;
            }
            .menu-link {
                margin: .1em;
                padding: .3em;
                color: #fff;
                text-decoration: none;
                background: dodgerblue;
                list-style: none;
            }
            .menu-active {
                background: orange;
            }
            .menu {
                background-color: yellowgreen;
            }
        </style>
    </head>
<body>
    <h1 id="main-title">Event</h1>

    <nav class="menu">
        <a href="#" class="menu-link" data-menu="1">menu 1</a>
        <a href="#" class="menu-link" data-menu="2">menu 2</a>
        <a href="#" class="menu-link" data-menu="3">menu 3</a>
    </nav>

 

 

이어서 다음은 javascript입니다.

 

<script>
var menu = document.querySelector('.menu');

function clickHandler(e){    // eventHandler써주면 자동으로 들어오지만 활용하려면 e를 써주기.  e는 이벤트 객체로써, 발생한 이벤트에 대한 많은 정보를 담고 있는 객체.
    console.log(e.target);    // event 객체의 타겟
    console.log(e.currentTarget);
    console.log(this);   // this는 menu이다. menu가 addEventLisner를 호출하였으므로
    console.log(this == e.currentTarget);
}

menu.addEventListener('click', clickHandler);

</script>
</body>
</html>

 

코드 해석

맨 마지막 줄 addEventListner 메서드를 통해 <menu에 클릭이라는 이벤트가 발생했을 시, clickHandler라는 특정 함수가 실행>되도록 합니다.

clickHandler 함수의 매개변수에 <e>를 써주었습니다. <e>는 '이벤트 객체'로써 현재 클릭이라는 이벤트를 발생했으니 그 클릭에 대한 상세한 정보를 담고 있겠죠? screenX (마우스 커서가 모니터 왼쪽 경계로부터 떨어진 픽셀 거리), clientX (마우스 커서가 브라우저 표시 영역 상의 X좌표), ctrlKey (Ctrl 키 눌려진 여부), currentTarget (이벤트 버블링 단계에서의 현재 요소를 가리킴) 등 정말 많은 정보를 확인할 수 있습니다! 이 정보는 console.log(e)를 통해서 한 번 출력해보세요.

 

 

 

  • console.log( e.target )

event 객체의 타깃을 말하는데, 현재 menu 1 버튼을 눌렀다면 menu 1에 대한 태그가 나옵니다.

실제 출력값 : <a href="#" class = 'menu-link' data-menu = "1"> menu 1 </a>

 

 

  • console.log( e.currentTarget )

target은 '이벤트가 타깃 요소에 최종 전파되는 단계'라고 한다면, currentTarget은 '맨 아래 요소 타깃에서 발생한 이벤트가 점차 상향 Window 객체까지 전파되는 단계' 라고 볼 수 있습니다. 따라서 menu 1 버튼을 클릭했더라도 menu 태그가 출력되는 것을 확인할 수 있습니다.

실제 출력값 : <nav class = "menu"> .... </nav>

 

 

  • console.log( this )

this 가 가리키는 것은 무엇일까요? 그것은 currentTarget 과 동일한 이벤트 객체입니다. 애초에 menu에 addEventListener라는 함수를 통해서 이벤트를 걸어주었기 때문에 인자는 menu 로 넘어가게 된 것이죠.

따라서 다음 줄의 console.log(e.currentTarget == this ) 의 결과값은 true로 나오게 됩니다.

 

 

 

 

 

 

 

이번에는 '클릭하면 파란색 메뉴 버튼이 오렌지 색으로 변하는 메뉴 활성화 버튼' 실습을 하겠습니다.

 

 

 

 var currentMenu; // 현재 활성화된 메뉴를 담아내는 객체
 var menu = document.querySelector('.menu');

 function clickHandler(e){ 
     if (currentMenu){
         currentMenu.classList.remove('menu-active');
     }
    e.target.classList.add('menu-active');
    currentMenu = e.target;
 }

 menu.addEventListener('click', clickHandler);

 

코드 해석

먼저 currentMenu 라는 현재 활성화된 메뉴를 담아내줄 객체를 선언합니다. 초기 상태에는 비어있는 null 값 상태입니다. 마지막 줄에는 menu에 클릭이라는 이벤트를 걸어주면 clickHandler라는 특정함수가 실행되도록 합니다.

 

그리고 clickHander 함수 인자에 e를 써주어서 이벤트 객체를 활용할 수 있게끔 해야겠죠?

먼저 if문으로 우리는 currentMenu 변수에 값이 있는지 체크한 후, 있다면 menu-active의 클래스를 삭제해주어야 합니다. 왜냐하면 다음 코드 실행시, 메뉴를 활성화하도록 클래스를 추가해주어야 하는데 이전 버튼이 이미 활성화(오렌지색)되어 있는 상태로 남아있게 되기 때문입니다.

 

e.target 으로 이벤트 객체의 타깃에 menu-active 클래스를 추가한 후, currentMenu 변수에 넣어주는 작업을 합니다.

 

 

 

 

 

 

 

 

참고로 실제로 저렇게 코드를 작성하기보단 이벤트 핸들러 함수 안에는 간결하게 작성 하는게 좋습니다.

 

 

 

// 위 방법도 좋지만 함수를 따로따로 만들어서 사용하는게 더 좋다
var currentMenu;
var menu = document.querySelector('.menu');


function inactivate(elem){
    elem.classList.remove('menu-active');
}

function activate(elem){
    elem.classList.add('menu-active');
    currentMenu = elem;
}
function clickHandler(e){    // 보통 이벤트 handler 안에 길게 쓰기 보다 함수를 쓴다.
    if (currentMenu){
        inactivate(currentMenu);
    }
    activate(e.target);
}

menu.addEventListener('click', clickHandler);

 

 

 

이렇게 작성할 시 장점

함수를 가져다 쓸 수 있습니다. 탭메뉴를 예를 들어보면 메뉴 클릭시 계속 열려져 있는 경우 있죠?

예를 들어 여기서 1번 탭 메뉴를 클릭하면 1번 메뉴는 계속 열려져 있어야 합니다.

그럴 땐 이렇게 코드를 활용합니다.

activate(document.querySelectorAll('.menu-link')[0]);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<실습 결과물>