addEventListener 위치의 중요성
jQuery 에서는 그냥
$(document).on("click", "element_query", function () {
});
이런 식으로 작성하면, document가 다 Load 되고나서 저 클릭 이벤트가 실행되도록 할 수 있었다.
하지만 바닐라 자바스크립트에서는 그걸 어떻게 해야할까 찾아보다가
window.onload = event => () { });
window.addEventListener("load", (event) => { });
document.addEventListener("readystatechange", (event) => { });
document.addEventListener("DOMContentLoaded", (event) => { });
등의 방법이 있다는 걸 알게 되었다.
하지만, 그럼에도 불구하고 문제를 해결할 수 없었는데,
문제가 뭐였냐면,

여기서 todo 혹은 done 리스트가 페이지가 로드되는 과정에서 데이터를 불러와서 하나씩 append 하는 방식이었는데,
내가 리스트에 있는 버튼들의 이벤트핸들러를 설정해줄 때,
버튼의 변수는 페이지 로드가 다 끝나기 전에 선언 및getElementbyID 혹은 querySelector로 할당을 해주었는데, 이벤트핸들러를 addEventListner로 설정해주는 건 페이지 로드가 다 끝나고 했던 것이다.
때문에, 설정한 변수는 undefined 여서 이벤트핸들러가 설정되지 않았던 것이다.
해결 방법은 두 가지.
1번도 당장 코드가 실행되는 데에는 지장이 없지만, 코드의 아름다움을 위해서는 2번이 맞는 선택이다.
동시에 자판 2개 이상 누를 때 이벤트 처리
todolist의 입력창을 input 에서 textarea 로 변경했는데, 원래 Enter 키를 누르면 addTodo() 함수가 실행되도록 해놨었다. 그러면 줄바꿈을 못하니 textarea 를 쓰는 이유가 없어진다.
그래서 Enter 키가 아니라, cmd + Enter 키를 누를 때 addTodo() 함수를 실행하고 싶었다.
검색해보니 여러 방법들이 있었는데,
이 방법이 가장 직관적이고 깔끔해 보였다.
(참고로 Mac 에서 cmd 버튼의 keycode는 "Meta" 이다.)
keyPressed = {};
inputBox.addEventListner("keydown", (event) => {
keyPressed[event.key] = true;
if (keyPressed["Meta"] && event.key === "Enter") {
addTodo();
}
});
inputBox.addEventListner("keyup", (event) => {
delete keyPressed[event.key];
}
자판을 누를 때마다(keydown) keyPressed라는 object에 해당 자판키의 키코드와 true를 각각 key, value로 저장하고,
자판에서 손을 땔 때마다(keyup) 해당 element를 keyPressed에서 삭제한다.
그리고 이미 "Meta" 키가 keyPressed에 저장되어 있다면, 즉 cmd 자판키가 눌려진 상태라면 Enter 키를 눌렀을 때 addTodo() 가 실행되는 방식이다.
[추가]
나중에 검색하다 알게 된 건데,
이미 이런 상황을 고려했는지, 간단한 메소드가 있었다.
shift, ctrl, alt, meta 키와 일반 키를 동시에 눌렀을 때 위와 같은 방식으로 이벤트를 줄 수 있다.
event.shiftKey
event.ctrlKey
event.altKey
event.metaKey
출처: https://im-developer.tistory.com/20 [Code Playground:티스토리]