첫 게시글로 무엇을 할까 고민을 많이 했는데, 최근에 겪었던 문제와 해결했던 과정에 대해서 적어볼까 한다.
문제설명
드롭 이벤트에 DOM이 바뀌는 이벤트를 걸어주어서, DOM이 바뀌니까 내가 걸어줬던 이벤트가 없어졌다.
바뀔때마다 새로 걸어주는 것 보다 좋은 방법이 없을까?
이벤트 위임으로 해결 하면 된다!
이벤트 위임을 알기 전에, 버블링과 캡쳐링 개념에 대해 알아보자.
이벤트 흐름은 3단계가 있는데, 캡쳐링 -> 타깃 -> 버블링 단계로 이루어진다.
이벤트 캡쳐링이란?
최상위 요소에서 가장 안쪽에 있는 타깃까지 이벤트가 내려가는 단계!
addEventListener
하고 인자로 capture:true
를 해야 캡쳐링때 이벤트 핸들러가 동작함.
이벤트 버블링이란?
한 요소의 이벤트 핸들러가 동작하고 부모 요소의 핸들러가 동작하고, 또 그 부모 요소의 해들러가 동작하는 것. 그렇게 최상단 요소까지 진행된다.
(버블링과 캡쳐링을 막는 것이 그 유명한 event.stopPropagation()
)
나는 이 중에서 버블링을 이용할 것임.
DOM이 바뀌지 않는 곳에 이벤트를 걸어주고, 하위에서 버블링으로 이벤트핸들러가 올라오면 내가 걸어준 이벤트가 실행이 됨.
회사에서 작성한 코드는 공개가 힘들고, 예시를 만들어보자면!
<!DOCTYPE HTML>
<html>
<head>
<style>
.up {
width: 300px;
height: 300px;
background-color: black;
color: white;
}
.middle {
width: 200px;
height: 200px;
background-color: blue;
color: white;
}
.down {
width: 100px;
height: 100px;
background-color: green;
color: white;
}
</style>
</head>
<body>
<div class="up">
내가 바로 상단의 이벤트를 받을곳!
<div class="middle">난 아무것도 아님!
<div class="down">난 이곳에 이벤트를 걸고 싶어!</div>
</div>
</div>
</body>
<script>
const upSelector = document.querySelector('.up');
const downSelector = document.querySelector('.down');
upSelector.addEventListener('click', (e) => {
if(e.target === downSelector) alert('event!');
} )
</script>
</html>
다음으로 드롭이벤트가 먹지 않던 문제는 간단했다.
dragover 중에 e.preventdefault()
를 넣으니까 해결.
어플리케이션의 대부분은 drop 속성이 허용되지 않아서 그것을 막고 drop을 허용시키는 것임! (참고자료)
https://stackoverflow.com/questions/21339924/drop-event-not-firing-in-chrome
https://joshua1988.github.io/web-development/javascript/javascript-interview-3questions/
https://ko.javascript.info/bubbling-and-capturing