JavaScript_마우스 이벤트

cindycho_0423·2023년 8월 13일
1

마우스 버튼 이벤트

🔸 MouseEvent.button

0: 마우스 왼쪽 버튼
1: 마우스 휠
2: 마우스 오른쪽 버튼
3: X1 (일반적으로 브라우저 뒤로 가기 버튼)
4: X2 (일반적으로 브라우저 앞으로 가기 버튼)

🔸 MouseEvent.type

click: 마우스 왼쪽 버튼을 눌렀을 때
contextmenu: 마우스 오른쪽 버튼을 눌렀을 때
dbclick: 동일한 위치에서 빠르게 두 번 click 할 때
mousedown: 마우스 버튼을 누른 순간
mouseup: 마우스 버튼을 눌렀다 뗀 순간

하나의 동작에 여러 이벤트가 발생하는 경우에 각각의 순서들을 잘 이해해두는 것이 중요하다.

ex) click 이벤트
-> mousedown 이벤트가 발생했습니다.
-> mouseup 이벤트가 발생했습니다.
-> click 이벤트가 발생했습니다.

ex) dblclick 이벤트
-> mousedown 이벤트가 발생했습니다.
-> mouseup 이벤트가 발생했습니다.
-> click 이벤트가 발생했습니다.
-> mousedown 이벤트가 발생했습니다.
-> mouseup 이벤트가 발생했습니다.
-> click 이벤트가 발생했습니다.
-> dblclick 이벤트가 발생했습니다.

또한 윈도우 체제와 mac os 체제에 따라서 이벤트가 다르게 발생할 수도 있다.

마우스 이동 이벤트

🧡 MouseEvent.type

mousemove: 마우스 포인터가 이동할 때
mouseover: 마우스 포인터가 요소 밖에서 안으로 이동할 때
mouseout: 마우스 포인터가 요소 안에서 밖으로 이동할 때

🔸 mousemove

const box1 = document.querySelector('#box1');

function onMouseMove() {
  console.log('mouse is moving!');
}

box1.addEventListener('mousemove', onMouseMove);

mousemove와 같이 마우스가 이동할 때 발생하는 이벤트에는 위치와 관련된 이벤트 객체의 프로퍼티들이 많이 활용된다. 대표적으로 client, page, offset 프로퍼티를 사용한다.

MouseEvent.clientX, clientY
: 화면에 표시되는 창 기준 마우스 포인터 위치

MouseEvent.pageX, pageY
: 웹 문서 전체 기준 마우스 포인터 위치

MouseEvent.offsetX, offsetY
: 이벤트가 발생한 요소 기준 마우스 포인터 위치

🔸 client, page, offset 차이

  1. clientX, clientY
    client 프로퍼티는 말 그대로 클라이언트 영역 내에서 마우스의 좌표 정보를 담고 있다. 클라이언트 영역이라는 이벤트가 발생한 순간에 브라우저가 콘텐트를 표시할 수 있는 영역을 뜻한다.

clientX: 브라우저가 표시하는 화면 내에서 마우스의 X좌표 위치를 담고 있다.
clientY: 브라우저가 표시하는 화면 내에서 마우스의 Y좌표 위차를 담고 있다.

client 값은 그 순간 보여지는 화면을 기준으로 계산하기 때문에 스크롤 위치와는 무관하게 항상 보여지는 화면의 좌측 상단의 모서리 위치를 (0,0)으로 계산한다.

  1. offsetX, offsetY
    offset 프로퍼티는 이벤트가 발생한 target이 기준이 된다.

offsetX: 이벤트가 발생한 target 내에서 마우스의 X좌표 위치를 담고 있다.
offsetY: 이벤트가 발생한 target 내에서 마우스의 Y좌표 위치를 담고 있다.

offset 값도 이벤트가 발생한 대상을 기준으로 계산하기 때문에 스크롤 위치와는 무관하게 항상 대상의 좌측 상단의 모서리 위치를 (0,0)으로 계산한다.

  1. pageX, pageY
    page 프로퍼티는 전체 문서를 기준으로 마우스 좌표 정보를 담고 있다. 그렇기 때문에 스크롤로 인해서 보이지 않게된 화면의 영역까지 포함해서 측정한다는 점이 앞의 두 프로퍼티와의 차이점이다.

🔸 mouseover & mouseout

const box2 = document.querySelector('#box2');

function printEventDate(e) {
  console.log(e.type);
}

box2.addEventListener('mouseover', printEventData);
box2.addEventListener('mouseout', printEventData);

이 코드를 실행하면 마우스가 요소 안으로 들어갈 때 mouseover,
마우스가 요소 밖으로 빠져나갈 때 mouseout 이벤트가 발생한다.

버블링에 의해서 자식요소들끼리도 이벤트 요소가 동작하는 것을 확인할 수 있다. mouseout, mouseover 순서대로 이벤트가 두 번 발생을 한다. 직전요소에서 빠져나올 때 mouseout이 일어나고 다음 요소로 들어갈 때 mouseover가 발생하는 것이다.
그래서

const box2 = document.querySelector('#box2');

function printEventDate(e) {
  if(e.target.classList.contains('cell')) {
    e.target.classList.toggle('on');
}

box2.addEventListener('mouseover', printEventData);
box2.addEventListener('mouseout', printEventData);

이런 식으로 토글 메소드를 사용하면 mouseover에서 클래스가 추가되고, mouseout에서 클래스가 삭제되는 방식으로 동작한다. 이런식으로 이벤트 위임을 사용할 수도 있다.

MouseEvent.relatedTarget

또한 mouseover와 mouseout의 이벤트에는 relatedTarget이라는 특별한 프로퍼티가 있다. target 프로퍼티가 이벤트가 발생한 요소를 담고 있다면, relatedTarget 프로퍼티는 이벤트가 발생하기 직전(또는 직후)에 마우스가 위치해 있던 요소를 담고 있다.

🔸 mouseenter / mouseleave

mouseenter는 mouseover처럼 마우스 포인터가 요소 바깥에서 안쪽으로 들어갈 때,
mouseleave는 mouseout처럼 마우스 포인터가 요소 안쪽에서 바깥으로 나갈 때 발생한다. 그렇다면 이 둘의 차이점에 대해서 알아보자.

  1. 버블링이 일어나지 않는다.
    mouseenter와 mouseleave는 버블링이 일어나지 않는다.

당연히 해당 요소 바깥에서 안쪽으로 마우스 커서가 이동할 때도 이벤트가 발생하지만, 버블링과 이벤트 위임의 원리로 자식요소인 부분으로 마우스 커서가 이동할 때도 이벤트가 발생한다.

하지만 mouseenter 타입의 이벤트 핸들러는 해당 요소 바깥에서 안쪽으로 마우스 커서가 이동할 때만 이벤트 핸들러가 동작하는 모습을 볼 수 있다.

  1. 자식 요소의 영역을 계산하지 않는다.
    mouseenter와 mouseleave는 자식 요소의 영역을 계산하지 않는다. 버블링에 의해 자식 요소로 마우스 커서가 이동할 때도 이벤트 핸들러가 동작하지만, 자식 요소에서 다시 부모 요소로 마우스 커서가 이동할 때도 이벤트 핸들러가 동작한다. mouseover는 자식 요소의 영역을 구분하기 때문이다.

반면, mouseenter는 자식 요소의 영역을 구분하지 않기 때문에 mouseenter 타입으로 이벤트 핸들러가 등록된 요소에서는 자식요소에서 이벤트 핸들러가 동작하지 않는 것뿐만 아니라 자식 요소의 영역에 들어갔다 나올 때도 이벤트 핸들러가 동작하지 않는다.

🔅정리
간단하게 정리하면, 이벤트가 자식 요소에 영향끼치는지가 둘의 가장 큰 차이라고 할 수 있다. 그래서 이벤트 핸들러가 자식 요소에까지 영향을 끼치게 하고싶은 경우에는 mouseover / mouseout을, 자식 요소에는 영향을 끼치지 않고 해당 요소에만 이벤트 핸들러를 다루고자 한다면 mouseenter / mouseleave를 활용하면 된다.

참고로 mouseenter, mouseleave, mouseover, mouseout, mousemove 처럼 마우스 이동과 관련된 이벤트에서는 값이 null이나 undefined가 아니라 0이다.


mouse 이벤트 타입설명
mousedown마우스 버튼을 누르는 순간
mouseup마우스 버튼을 눌렀다 떼는 순간
click왼쪽 버튼을 클릭한 순간
dblclick왼쪽 버튼을 빠르게 두 번 클릭한 순간
contextmenu오른쪽 버튼을 클릭한 순간
mousemove마우스를 움직이는 순간
mouseover마우스 포인터가 요소 위로 올라온 순간
mouseout마우스 포인터가 요소에서 벗어나는 순간
mouseenter마우스 포인터가 요소 위로 올라온 순간 (버블링이 일어나지 않음)
mouseleave마우스 포인터가 요소에서 벗어나는 순간 (버블링이 일어나지 않음)

mouse 위치 프로퍼티설명
clientX, clientY마우스 포인터의 브라우저 표시 영역에서의 위치
pageX, pageY마우스 커서의 문서 영역에서의 위치
offsetX, offsetY마우스 포인터의 이벤트 발생한 요소에서의 위치
screenX, screenY마우스 포인터의 모니터 화면 영역에서의 위치
profile
https://linktr.ee/Hyunji_Cho 🐣

1개의 댓글

comment-user-thumbnail
2023년 8월 16일

잘 읽고 갑니다!

답글 달기

관련 채용 정보