공부방/jQuery

이벤트 처리기가 동적으로 생성된 요소에 이벤트를 처리 못했던 이유

EVO. 2023. 5. 24. 01:32

https://babgeuleus.tistory.com/58

 

14주차 CafeMate 주문 관리 프로세스 구현

 

babgeuleus.tistory.com

다음 글에서 진행중 메뉴들을 동적으로 받아오고 동적으로 받아온 메뉴들에 +와 -버튼에 클릭이벤트를 달아주었습니다.

 

문제 제기

 

//+버튼 구현 
$(".increase-qty").click(function() { 
console.log("도착"); 
let menuValue = $(this).attr("id").replace("-plus", ""); 
let menuPrice = parseInt($(this).data("price")); 
let currentQty = parseInt($("#" + menuValue + "-qty").val()); 
$("#" + menuValue + "-qty").val(currentQty + 1); updateTotal(menuPrice); 
});

하지만 +버튼을 눌러도 콘솔의 내용이 찍히지 않았고 이 코드를 먼저 document에 등록해야하나 싶어 <head>태그 안에 집어넣어보기도 하고 

$(document).ready(function (){
//메뉴들 렌더링
});

메뉴들 렌더링 하는 곳에 집어넣어보기도 했지만 다 되지 않았습니다.

 

문제 원인과 해결

이전에 작동하지 않았던 이유는 이벤트 처리기가 동적으로 생성된 요소에 대해 클릭 이벤트를 처리할 수 없었기 때문입니다. 원래의 코드에서 이벤트 처리기는 페이지가 처음 로드될 때만 바인딩되므로, 그 시점에 존재하지 않은 요소에는 이벤트가 처리되지 않습니다.

 

수정 전의 코드는 오직 정적인 요소에만 이벤트를 처리 할 수 있었습니다. 그래서 동적으로 생성된 메뉴 아이템의 +  - 버튼은 이벤트가 처리되지 않았습니다.

수정된 코드는 $(document).on("click", ..) 문법을 사용하여 이벤트 처리기를 문서 전체에 바인딩합니다.

 

//+버튼 구현
$(document).on("click", ".increase-qty", function() {
  console.log("도착");
  let menuValue = $(this).attr("id").replace("-plus", "");
  let menuPrice = parseInt($(this).data("price"));
  let currentQty = parseInt($("#" + menuValue + "-qty").val());
  $("#" + menuValue + "-qty").val(currentQty + 1);
  updateTotal(menuPrice);
});

 

 

 

이를 통해 이벤트 처리기는 페이지에 존재하지 않았던 동적으로 추가된 요소에 대한 클릭 이벤트에도 적용됩니다.

$(document).on("click", ..)를 사용하면 이벤트는 상위 요소(여기서는 document)로 전파되며, 이벤트 처리기는 원하는 하위 요소에 프록시를 만듭니다. 이렇게 하면 동적으로 추가된 요소에 이벤트를 처리할 수 있게 됩니다.

이런 방식을 이벤트 위임(delegation)이라고 부릅니다.

이러한 방법으로 수정된 코드가 작동하는 이유는 이벤트 위임을 통해 클릭 이벤트가 동적으로 생성된 요소에도 처리되기 때문입니다.

 

자바스크립트 개념이 부족하니 이 사단이 난것 같습니다..