<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.event-container {
border: 1px solid black;
height: 40vh;
width: 80vh;
display: flex;
perspective: 1000px;
}
.event {
flex: 1;
background: skyblue;
color: white;
font-size: 2rem;
transition: all 2s;
}
.event:hover {
transform: rotateY(45deg);
background: blue;
}
</style>
</head>
<body>
<div class="event-container">
<button class="event" data-id="1">
<span class="event-button-type">버튼</span
><span class="event-button-number">1</span>
</button>
<button class="event" data-id="2">
<span class="event-button-type">버튼</span
><span class="event-button-number">2</span>
</button>
<button class="event" data-id="3">
<span class="event-button-type">버튼</span
><span class="event-button-number">3</span>
</button>
</div>
<script>
(function () {
const eventContainer = document.querySelector(".event-container");
eventContainer.addEventListener("click", function (e) {
console.log(e.target);
});
})();
</script>
</body>
</html>
위의 코드를 확인해보면 eventContainer 하나에만 event를 줬음에도 불구하고 e.target이라는 속성을 통해 클릭된 현재 객체에 대해 정보를 가져오는것을 확인할 수 있다. 이를 이벤트 위임이라고 한다.
addEventListener의 수가 늘어갈수록 브라우저의 속도가 느려질수 있기때문에 이벤트위임을 잘 활용하는것이 중요하다.
여기서 우리는 각 버튼을 클릭할때마다 button에 있는 data-id를 가져오려고한다.
<script>
(function () {
const eventContainer = document.querySelector(".event-container");
eventContainer.addEventListener("click", function (e) {
console.log(e.target.dataset);
});
})();
</script>
위와같이 버튼 전체를 클릭하는 경우에는 dataset이 나타나게 되어있지만 버튼이나 1, 2, 3 등의 span태그 내부를 누르는경우 정상적으로 dataset 을 가져올 수 없게된다.
이를 해결하는 방법이 두가지 있는데 첫번째는 css로 해결하는 방법이다.
pointer-events
pointer-events 를 none으로 선택하게되면 해당 속성은 이벤트가 전파되어 가지 않는다.
.event-button-type,.event-button-number{
pointer-events: none;
}
두번쨰는 자바스크립트 방식이 있다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.event-container {
padding:20px;
border: 1px solid black;
height: 40vh;
width: 80vh;
display: flex;
perspective: 1000px;
}
.event {
flex: 1;
background: skyblue;
color: white;
font-size: 2rem;
transition: all 2s;
}
.event:hover {
transform: rotateY(45deg);
background: blue;
}
/* .event-button-type,.event-button-number{
pointer-events: none;
} */
</style>
</head>
<body>
<div class="event-container">
<button class="event" data-id="1">
<span class="event-button-type">버튼</span
><span class="event-button-number">1</span>
</button>
<button class="event" data-id="2">
<span class="event-button-type">버튼</span
><span class="event-button-number">2</span>
</button>
<button class="event" data-id="3">
<span class="event-button-type">버튼</span
><span class="event-button-number">3</span>
</button>
</div>
<script>
(function () {
const eventContainer = document.querySelector(".event-container");
eventContainer.addEventListener("click", function (e) {
let element = event.target;
while(!element.classList.contains('event')){
element = element.parentNode;
if(element.nodeName === 'BODY'){
element = null;
return;
}
}
console.log(element.dataset);
});
})();
</script>
</body>
</html>
while을 활용해서 해당 클릭한 요소가 datasets을 가지고있지 않으면 element 요소를 부모로 확장하는 방식이다.
다만 body까지 올라간 경우에는 해당 요소가 존재하지 않기때문에 if 분기로 return 처리해준다.
'JavaScript > javascript 활용하기' 카테고리의 다른 글
CSS - 스크롤 이벤트 (0) | 2020.12.06 |
---|---|
CSS - 움직이는 문 만들기 (0) | 2020.12.03 |
javascript를 활용한 tic tac toe 만들어보기 (0) | 2020.07.08 |
자바스크립트를 활용해 현재 날짜부터 마지막 날짜 구하기 (0) | 2020.03.04 |
자바스크립트 2중 for문을 활용한 좌석 만들기 (4) | 2020.03.03 |