브라우저 이벤트

Happhee·2022년 5월 26일
0

AvenJS

목록 보기
17/17
post-thumbnail

✨ 자주 사용되는 DOM 이벤트

Mouse

  • click
    요소 위에서 마우스 왼쪽 버튼을 눌렀을 때(터치스크린이 있는 장치에선 탭 했을 때)

  • contextmenu
    요소 위에서 마우스 오른쪽 버튼을 눌렀을 때

  • mouseover mouseout
    마우스 커서를 요소 위로 움직였을 때
    커서가 요소 밖으로 움직였을 때

  • mousedown mouseup
    요소 위에서 마우스 왼쪽 버튼을 누르고 있을 때
    마우스 버튼을 뗄 때

  • mousemove
    마우스를 움직일 때

Form

  • submit
    사용자가 <form>을 제출할 때

  • focus
    사용자가 <input> 같은 요소에 포커스 할 때

Keyboard

keydown과 keyup
사용자가 키보드 버튼을 누르거나 뗄 때 발생합니다.

문서

DOMContentLoaded
HTML이 전부 로드 및 처리되어 DOM 생성이 완료되었을 때

CSS

transitionend
CSS 애니메이션이 종료되었을 때 발생합니다.


✨ Event handler

이벤트에 발생했을 때 실행시킨 함수를 handler라고 하며, 이는 여러가지 방법으로 할당할 수 있다.

HTML 속성

👇 HTML 안의 on<event>에 핸들러를 할당한다.

<input value="AvenJS???" type="button" onclick="alert('AvenJS는 Event Handler 연습중')" >

버튼을 클릭하면 onclick안의 코드가 실행된다!
하지만, 이런식으로 함수를 작성하는 것보다 호출 함수를 따로 만들어서 코드를 짜는 것이 좋다.

<script>
  function countAvenJS() {
    for(let i=1; i<=4; i++) {
      alert(`AvenJS 는 총 ${i}`);
    }
  }
</script>

<input  value="AvenJS를 세봅시다!" type="button" onclick="countAvenJS()">

HTML 속성은 대·소문자를 구분하지 않지만, 속성값은 대개 onclick 같이 소문자로 작성한다.

DOM 프로퍼티

👇 DOM 프로퍼티 on<event>에 핸들러를 할당할 수 있다.

<input id="elem" value="AvenJS???" type="button">
<script>
  elem.onclick = function() {
    alert('AvenJS는 Event Handler 연습중');
  };
</script>

다만, 프로퍼티는 단 하나뿐이기에 여러 개의 이벤트 핸들러를 할당하는 것은 불가능하다.
👇 이를 무시하고 추가할 경우, 기존 핸들러가 덮어씌워진다.

<input id="elem" value="AvenJS???" type="button" onclick="alert('AvenJS는 Event Handler 이전 연습중')">
<script>
  elem.onclick = function() {
    alert('AvenJS는 Event Handler 이후 연습중');
  };
</script>

만약 여기서 이벤트 핸들러를 제거하고 싶다면 null을 할당하면 된다.

elem.onclikc = null

또한, this로 접근하는 것도 가능하다.

<button onclick="alert('this.innerHTML')"> AvenJS는 Event Handler 연습중</button>

DOM 프로퍼티는 대/소문자를 구분한다.


❗️ 조심해야 할 부분 ❗️

function removeAllBurger() {
  localStorage.clear();
  cartList.innerHTML = "";
  cartPrice.innerHTML = "0";
}
// correct 
elem.onclick = removeAllBurger;

// wrong
elem.onclick = removeAllBurger();

( )괄호를 붙이게 되면 함수를 즉시 호출하겠다는 것이기에 여기서 removeAllBurger는 반환 값이 없으므로 undefined가 onclick 프로퍼티에 할당된다.

❗️ 하지만 HTML 속성 값에는 괄호가 있어야 한다 ❗️

<input type="button" id="button" value="버거삭제" onclick="removeAllBurger()">

브라우저는 속성값을 읽고 속성값을 함수 본문으로 하는 핸들러 함수를 만들기 때문이다.

button.onclick = function() {
  removeAllBurger(); // 속성값
};

❌ setAttribute ❌

document.body.setAttribute('onclick', function(){ localStorage.clear() });

속성은 항상 문자열이기 때문에, 함수가 문자열이 되어버리기에 body를 클릭하면 에러가 난다.


✨ addEventListener

HTML 속성과 DOM 프로퍼티를 이용한 이벤트 핸들러 할당 방식으로는 복수의 핸들러를 할당할 수 없는 핸들러 덮어씌우기 현상이 나타나게 된다.

이를 해결하기 위해 등장한 문법이 바로 addEventListener이다.

element.addEventListener(event, handler, [options])
  • event 이벤트이름 👉 click
  • handler 핸들러 함수
  • options
    • once
      true이면 이벤트가 트리거 될 때 리스너가 자동으로 삭제
    • capture
      어느 단계에서 이벤트를 다뤄야 하는지를 알려주는 프로퍼티
    • passive
      true이면 리스너에서 지정한 함수가 preventDefault()를 호출하지 않음

핸들러의 삭제는 removeEventListener로 진행한다.

element.removeEventListener(event, handler, [options]);

다만, 이때 handler를 변수로 저장해두지 않으면 제대로 동작하지 않는다.

elem.addEventListener( "click" , () =>  localStorage.clear());
//  ❌ 작동 안함 ❌
elem.removeEventListener( "click", () =>  localStorage.clear());


function handleRemoveAllBurger() {
 localStorage.clear();
}

input.addEventListener("click", handleRemoveAllBurger);
// 👌 작동 👌
input.removeEventListener("click", handleRemoveAllBurger);

addEventListener를 여러 번 호출하면 여러 개의 핸들러를 붙일 수 있다.

<input type="button" id="button" value="버거삭제">

<script>
function handleRemoveAllBurger1() {
  localStorage.clear();
}
function handleRemoveAllBurger2() {
  cartList.innerHTML = "";
  cartPrice.innerHTML = "0";
}
button.addEventListener("click", handleRemoveAllBurger1);
button.addEventListener("click", handleRemoveAllBurger2); 
</script>

✨ event object

이벤트가 발생하면 브라우저는 이벤트 객체를 만든다.
이곳에 이벤트에 대한 상세한 정보를 넣고, 핸들러에 인수 형태로 전달한다.

<input type="button" id="button" value="버거삭제">


<script>
  button.onclick = function(event) {
    // 이벤트 타입과 요소, 클릭 이벤트가 발생한 좌표를 보여줌
    alert(event.type + " 이벤트가 " + event.currentTarget + "에서 발생했습니다.");
    alert("이벤트가 발생한 곳의 좌표는 " + event.clientX + ":" + event.clientY +"입니다.");
  };
</script>
  • event.type 이벤트 타입
    위 예시에선 "click"

  • event.currentTarget 이벤트를 처리하는 요소.
    화살표 함수를 사용해 핸들러를 만들거나 다른 곳에 바인딩하지 않은 경우엔 this가 가리키는 값과 같다.
    화살표 함수를 사용했거나 함수를 다른 곳에 바인딩한 경우엔 event.currentTarget를 사용해 이벤트가 처리되는 요소 정보를 얻는다.

  • event.clientX / event.clientY
    포인터 관련 이벤트에서, 커서의 상대 좌표 ( 브라우저 화면 기준 좌표)


✨ 객체 형태의 handler / handlerEvent

addEventhandler를 사용하면 함수뿐만 아니라 객체까지도 handleEvent로 할당이 가능하다.

<input type="button" id="button" value="버거삭제">

<script>
let objHandlerRemoveAllBurger = {
  handleEvent(event){
    alert(event.type + " 이벤트가 " + event.currentTarget + "에서 발생했습니다.");
    localStorage.clear();
    cartList.innerHTML = "";
    cartPrice.innerHTML = "0";
  }
}
function handleRemoveAllBurger1() {

button.addEventListener("click", objHandlerRemoveAllBurger);
</script>

addEventListener가 인수로 객체 형태의 핸들러를 받으면 이벤트 발생 시, obj.handleEvent(event)가 호출된다.


📚 학습할 때, 참고한 자료 📚
모던 자바스크립트 : 브라우저 이벤트 소개

profile
즐기면서 정확하게 나아가는 웹프론트엔드 개발자 https://happhee-dev.tistory.com/ 로 이전하였습니다

0개의 댓글