코딩/Javascript

[JS-중급편-이벤트] 3. 마우스 이벤트

드리프트 2021. 2. 7. 19:17
728x170

 

 

사람들이 컴퓨터와 상호 작용하는 가장 일반적인 방법 중 하나는 마우스로 알려진 포인팅 장치를 사용하는 것입니다.

 

마우스 이벤트 만나보기

JavaScript에서 마우스를 다루는 주된 방법은 이벤트를 이용하는 것입니다.

 

마우스를 다루는 많은 이벤트가 있지만 여기서 모두 살펴보지는 않을 것입니다.

 

대신 다음과 같은 자주 사용하는 항목에만 초점을 맞출 겁니다.

 

  • click
  • dblclick
  • mouseover
  • mouseout
  • mouseenter
  • mouseleave
  • mousedown
  • mouseup
  • mousemove
  • contextmenu
  • mousewheel and DOMMouseScroll

 

마우스 이벤트의 이름은 이벤트가 수행하는 작업에 대한 좋은 힌트를 제공해서 대충 무슨 작동을 하는지 유추 할 수 있습니다.

 

다음 섹션에서 이러한 각 이벤트를 좀 더 자세히 살펴보겠습니다.

 

 

한번 클릭, 두 번 클릭

 

마우스 이벤트 중에서 가장 많이 쓰이는 클릭 이벤트부터 시작하겠습니다.

 

이 이벤트는 기본적으로 요소를 클릭하면 시작됩니다.

 

이 클릭 이벤트는 클릭하려는 요소위에서 마우스 버튼을 클릭하고 같은 요소위에서 손을 떼면 발생하는 이벤트입니다.

 

이 행위를 시각화해보면 다음가 같습니다.

 

 

클릭 이벤트로 작업하는 코드를 이미 몇 번 보았지만 좀 더 자세히 알아보겠습니다.

 

var button = document.querySelector("#myButton");
button.addEventListener("click", doSomething, false);

function doSomething(e) {
    console.log("Mouse clicked on something!");
}

 

 

클릭 이벤트가 발생되면 addEventListener에 의해 지정된 이벤트 리스너가 작동합니다.

 

다음은 두 번 클릭 즉, dblclick 대해 알아보겠습니다.

 

dblclick 이벤트는 기본적으로 클릭 동작을 두 배로 빠르게 반복할 때 발생하며 이를 사용하는 코드는 다음과 같습니다.

 

var button = document.querySelector("#myButton");
button.addEventListener("dblclick", doSomething, false);

function doSomething(e) {
    console.log("Mouse clicked on something...twice!");
}

 

dblclick 이벤트가 발생하는 각 클릭 사이의 시간은 코드를 실행 중인 OS를 기반으로 합니다.

 

브라우저에 특정한 것도 아니고 JavaScript를 사용하여 정의할 수 있는 것도 아닙니다.

 

한 개의 요소에 click 이벤트와 dblclick 이벤트 두 개를 동시에 지정하면 어떻게 될까요?

 

 

만약 사용자가 그 요소를 더블클릭하면 해당 이벤트 리스너는 3번 실행될 겁니다.

 

첫 번째 클릭에서 click 이벤트가 발생하고 두 번째 클릭에서 click 이벤트가 발생되고 마지막으로 더블클릭이니까 dblclick 이벤트가 발생된 상황인 겁니다.

 

 

마우스 오버, 마우스 아웃

 

일반적인 마우스 오버 및 마우스 아웃 시나리오는 각각 mouseover 및 mouseout 이벤트에 의해 처리됩니다.

 

 

다음은 이러한 두 가지 이벤트의 스니펫입니다.

 

var button = document.querySelector("#myButton");
button.addEventListener("mouseover", hovered, false);
button.addEventListener("mouseout", hoveredOut, false);

function hovered(e) {
    console.log("Hovered!");
}

function hoveredOut(e) {
    console.log("Hovered Away!");
}

 

위 코드를 보셨듯이 마우스 오버(mouseover)와 마우스 아웃(mouseout) 이벤트는 말 그대로 진짜 간단합니다.

 

 

마우스 엔터(mouseenter)와 마우스 리브(mouseleave)

 

우리는 무언가 위에 마우스를 올려놓고 무언가에서 멀리하는 두 가지 이벤트 (마우스 오버와 마우스 아웃)를 살펴보았습니다.

 

결과적으로 똑같은 일을 하는 이벤트가 두 개 더 있습니다.

 

이것은 mouseenter 및 mouseleave 이벤트입니다.

 

그러나 차이점은 있습니다. mouseenter 및 mouseleave 이벤트가 버블링 되지 않습니다.

 

즉 마우스를 가져가거나 떼려는 요소에 하위 요소가 있는 경우에만 중요합니다.

 

이 네 가지 이벤트는 모두 하위 요소가 없을 때 동일하게 작동합니다.

 

 

실행 중인 하위 요소가 있는 경우는

 

  1. mouseover 및 mouseout은 마우스를 자식 요소 위로 움직일 때마다 실행됩니다. 즉, 단일 영역 내에서 마우스를 움직이는 것처럼 보이지만 불필요한 이벤트 발생을 많이 볼 수 있습니다.
  2. mouseenter 및 mouseleave는 한 번만 실행됩니다. 마우스가 이동하는 자식 요소의 수는 중요하지 않습니다.

수행할 작업의 90 %에 대해 mouseover 및 mouseout으로 충분합니다.

 

약간 더 복잡한 UI를 만드는 경우에는 버블링이 없는 mouseenter 및 mouseleave 이벤트를 사용할 수 있다는 사실만 알고 계시면 될 듯합니다.

 

 

 

마우스다운(mousedown), 마우스 업(mouseup) 이벤트

 

click 이벤트의 거의 하위 구성 요소로 볼 수 있는 이벤트는 바로 mousedown 및 mouseup 이벤트입니다.

 

다음 다이어그램에서 이유를 알 수 있습니다.

 

 

 

마우스로 누르면 mousedown 이벤트가 발생합니다. 

 

누르기를 놓으면 mouseup 이벤트가 발생합니다. 눌렀다 놓은 요소가 동일한 요소이면 클릭 이벤트도 실행됩니다.

 

다음 스니펫에서 이 모든 것을 볼 수 있습니다.

 

var button = document.querySelector("#myButton");
button.addEventListener("mousedown", mousePressed, false);
button.addEventListener("mouseup", mouseReleased, false);
button.addEventListener("click", mouseClicked, false);

function mousePressed(e) {
    console.log("Mouse is down!");
}

function mouseReleased(e) {
    console.log("Mouse is up!");
}

function mouseClicked(e) {
    console.log("Mouse is clicked!");
}

 

"왜 이 두 이벤트에 대해 배워야 할까요?"라고 궁금해하실 수 있습니다.

 

click 이벤트는 mousedown 및 mouseup을 사용하려는 대부분의 경우에 완벽하게 작동됩니다.

 

그러나 mousedown 및 mouseup 이벤트가 필요할 경우 더 많은 제어를 제공한다는 점에서 이 이벤트를 알아둬야 할 필요가 있는 겁니다.

 

일부 드래그 같은 작업에서는 mousedown 이벤트가 발생했지만 mouseup 이벤트는 발생하지 않은 경우가 생기기 때문입니다.

 

 

 

이벤트가 계속 들릴 때

 

가장 번잡한 이벤트 중 하나는 mousemove 이벤트입니다.

 

이 이벤트는 mousemove 이벤트를 수신하는 요소 위로 마우스를 이동할 때 아주 많이 발생됩니다.

 

 

 

다음은 mousemove 이벤트의 예입니다.

 

var button = document.querySelector("#myButton");
button.addEventListener("mousemove", mouseIsMoving, false);

function mouseIsMoving(e) {
    console.log("Mouse is on the run!");
}

 

브라우저는 mousemove 이벤트가 적용되는 빈도를 제어하며 마우스가 단일 픽셀을 이동하면 이 이벤트가 시작됩니다.

 

이 이벤트는 예를 들어 마우스의 현재 위치가 추적과 관련된 UI에 적합합니다.

 

 

콘텍스트 메뉴

 

마지막으로 살펴볼 이벤트는 contextmenu입니다.

 

아시다시피 다양한 응용 프로그램에서 일반적으로 마우스 오른쪽 버튼을 클릭하면 메뉴가 표시됩니다.

 

 

 

이 메뉴를 콘텍스트 메뉴라고 합니다.

 

이 메뉴가 나타나기 직전에 바로 contextmenu 이벤트가 시작됩니다.

 

이 이벤트는 언제 쓰일까요? 솔직히 말해서 이 이벤트를 쓰는 주된 이유는 단 하나뿐입니다.

 

그 이유는 마우스 오른쪽 버튼을 클릭하거나 키보드 메뉴 버튼 또는 바로 가기 버튼을 사용할 때 이 메뉴가 나타나지 않도록 하기 위함입니다.

 

다음은 기본 동작을 방지하는 방법의 예입니다.

 

document.addEventListener("contextmenu", hideMenu, false);

function hideMenu(e) {
    e.preventDefault();
}

 

이벤트의 preventDefault 메서드는 기본 동작이 실제로 발생하는 것을 중지합니다.

 

메뉴가 나타나기 전에 contextmenu 이벤트가 시작되기 때문에 preventDefault를 호출하면 콘텍스트 메뉴가 표시되지 않습니다.

 

기본 동작이 실행되지 않습니다.

 

 

 

마우스 이벤트 속성

 

마우스 이벤트의 속성에 대해 좀 더 구체적으로 살펴보겠습니다.

 

지금까지 본 모든 마우스 이벤트는 MouseEvent를 기반으로합니다.

 

MouseEvent가 마우스 작업을 더 쉽게 해주는 많은 속성을 제공하기 때문에 세부 사항을 알아보는 것이 중요합니다.

 

그들 중 일부를 살펴 보겠습니다.

 

 

글로벌 마우스 위치

 

screenX 및 screenY 속성은 마우스 커서가 기본 모니터의 왼쪽 상단 위치에서 떨어진 거리를 반환합니다.

 

 

다음은 screenX 및 screenY 속성의 매우 간단한 예입니다.

 

document.addEventListener("mousemove", mouseMoving, false);

function mouseMoving(e) {
    console.log(e.screenX + " " + e.screenY);
}

 

페이지에서 적용되는 다른 여백 / 패딩 / 오프셋 / 레이아웃은 중요하지 않습니다.

 

반환되는 값은 항상 마우스가 현재 있는 위치와 기본 모니터의 왼쪽 상단 모서리 사이의 거리입니다.

 

 

 

브라우저 안에서의 마우스 위치

 

clientX 및 clientY 속성은 브라우저 (기술적으로 브라우저 뷰포트)의 왼쪽 상단 모서리를 기준으로 마우스의 x 및 y 위치를 반환합니다.

 

 

 

이에 대한 코드입니다.

 

var button = document.querySelector("#myButton");
button.addEventListener("mousemove", mouseMoving, false);

function mouseMoving(e) {
    console.log(e.clientX + " " + e.clientY);
}

 

이벤트 핸들러에 전달된 이벤트 인수의 clientX 및 clientY 속성을 호출하여 값을 가져옵니다.

 

 

어떤 마우스 버튼이 눌려졌을까요?

 

마우스에는 종종 여러 버튼이 있거나 여러 버튼을 시뮬레이션하는 방법이 있습니다. 

 

가장 일반적인 버튼 구성에는 왼쪽 버튼, 오른쪽 버튼 및 중간 버튼 (종종 마우스 휠 클릭)이 포함됩니다. 

 

어떤 마우스 버튼을 눌렀는지 알아내기 위해 button 속성이 있습니다. 

 

이 속성은 왼쪽 마우스 버튼을 눌렀을 경우 0, 가운데 버튼을 눌렀을 경우 1, 오른쪽 마우스 버튼을 눌렀을 경우 2를 반환합니다.

 

 

버튼 속성을 사용하여 어떤 버튼이 눌렸는지 확인하는 코드는 아래처럼 매우 쉽습니다.

 

document.addEventListener("mousedown", buttonPress, false);

function buttonPress(e) {
    if (e.button === 0) {
        console.log("Left mouse button pressed!");
    } else if (e.button === 1) {
        console.log("Middle mouse button pressed!");
    } else if (e.button === 2) {
        console.log("Right mouse button pressed!");
    } else {
        console.log("Things be crazy up in here!!!");
    }
}

 

 

마우스 휠 상대하기

마우스 휠은 지금까지 본 다른 모든 것에 비해 특별합니다.

 

명백한 차이점은 우리는 버튼이 아니라 휠을 다루고 있다는 겁니다.

 

관련된 이벤트는 두 가지가 있습니다.

 

Internet Explorer 및 Chrome에서 사용하는 mousewheel 이벤트와 Firefox에서 사용하는 DOMMouseScroll 이벤트가 있습니다.

 

이러한 마우스 휠 관련 이벤트를 수신하는 방법은 다음과 같습니다.

 

document.addEventListener("mousewheel", mouseWheeling, false);
document.addEventListener("DOMMouseScroll", mouseWheeling, false);

 

마우스 휠 및 DOMMouseScroll 이벤트는 마우스 휠을 임의의 방향으로 스크롤하는 순간 발생합니다.

 

마우스 휠을 스크롤하는 방향이 중요합니다.

 

해당 정보를 얻으려면 이벤트 처리기에서 이벤트 인수를 찾아야 합니다.

 

mousewheel 이벤트에 대한 이벤트 인수에는 wheelDelta라는 속성이 포함됩니다.

 

DOMMouseScroll 이벤트의 경우 이벤트 인수에 세부 속성이 있습니다.

 

이 두 속성은 마우스 휠을 스크롤하는 방향에 따라 값이 양수 또는 음수에서 변경된다는 점에서 비슷합니다.

 

주목해야 할 점은 여기서 mousewheel과 DOMMouseScroll의 양수 음수가  일치하지 않는다는 것입니다.

 

마우스 휠 이벤트와 관련된 wheelDelta 속성은 마우스 휠에서 위로 스크롤할 때 양수입니다.

 

아래로 스크롤하면 음수입니다. DOMMouseScroll의 detail 속성의 경우 정반대가 적용됩니다.

 

이 속성은 위로 스크롤하면 음수이고 아래로 스크롤하면 양수입니다.

 

이 wheelDelta 및 detail 정보 불일치를 다루는 것은 매우 간단합니다.

 

다음 스니펫에서 볼 수 있습니다.

 

function mouseWheeling(e) {
  let scrollDirection;
  let wheelData = e.wheelDelta;

  if (wheelData) {
    scrollDirection = wheelData;
  } else {
    scrollDirection = -1 * e.detail;
  }

  if (scrollDirection > 0) {
    console.log("Scrolling up! " + scrollDirection);
  } else {
    console.log("Scrolling down! " + scrollDirection);
  }
}

 

scrollDirection 변수는 wheelData 속성 또는 detail 속성에 포함된 값을 저장합니다. 

 

이 값이 양수인지 음수인지에 따라 동작을 특수하게 지정할 수 있습니다.

 

 

그리드형