#알아야 할 개념 :
● 개념_1 : Mouse 이벤트_2_마우스 포인터(움직이는 마우스) 관련 event
○ 정의 :Mouse 포인터에 관한 기본적인 event.type과 event.프로퍼티가 존재한다.
○ event.type : (5가지)
- 마우스 포인터가 요소 내 움직일 때, event.type : 'mousemove'
- 마우스 포인터가 요소 밖 => 안으로 움직일 때, event.type : 'mouseover' || 'mouseenter'
- 마우스 포인터가 요소 안 => 밖으로 움직일 때, event.type : 'mouseout' || 'mouseleave'
○ event.프로퍼티 :
- 마우스 포인터가 요소기준 위치값 반환메소드 : offset(X||Y)
- 마우스 포인터가 웹페이지 기준 위치값 반환메소드 : page(X||Y)
- 마우스 포인터가 브라우저 창의 크기 기준 위치값 반환메소드 : client(X||Y)
- 마우스의 현재 포인터된 요소노드값을 반환 : relatedTarget
※참고로 X,Y는 각 기준점의
- X : 오른쪽으로 갈수록 값이 증가한다.
- Y : 아래로 갈수록 값이 증가한다.
※ 활용 사례 : 마우스 포인터가 움직인 이동 방향을 client, page, offset 의 X,Y값으로 표현 가능 (★암기 X 이해 O)
- ↗ : X값 증가 , Y값 감소
- ↙ : X값 감소 , Y값 증가
- ↖ : X값 감소 , Y값 감소
- ↘ : X값 증가 , Y값 증가
● ★개념_2 : Mouse_커서이동 활용하기_1
○ Default 상황 :
부모 Box + 자식 Box 4개(cell 1, 2,3,4)
○ 요구조건 :
- cell1,2,3,4 중 하나에 마우스 포인터에 닿을 때, 투명도를 낮춰서 인식
- cell1,2,3,4에서 마우스 포인터를 벗어날 때, 투명도를 다시 높여 원상복귀
○ 핵심 해결과정 :
1_핸들러 function 작성 :
①. if(event.target.classList.contain('원래상태의 클래스')) //해당 마우스 포인터가 cell의 마우스 닿기 전 클래스인지를 확인
②. 있다고 하면, => e.target.classList.toggle('마우스포인터 가 있을 때, 투명도 낮추는 class css 적용')
2_ ★부모 Box에 addEventListener() 적용
- 부모Box요소노드.addEventListener('mounseover', 핸들러);
- 부모Box요소노드.addEventListener('mounseout', 핸들러);
○ 주의해야할 점 2가지 :
- 부모Box에 핸들러 적용할 때, mounseover, mounseover 두 type에 모두 추가 해야한다. //안그러면 마우스 포인터가 떠날시 원상복구가 안됨
- 'mouseenter', 'mouseleave'로 하면 안됨 //저걸로 하게 되면, 부모Box내 자식 cell들은 인식을 안함
○ 정답 :
const box = document.querySelector('.box');
//올려졌을 때, 효과 내기
function printEventData(e) {
if (e.target.classList.contains('boxes')) {
e.target.classList.toggle('done');
}
}
box.addEventListener('mouseover',printEventData );
box.addEventListener('mouseout',printEventData );
● ★개념_3 : Mouse_커서이동 활용하기_2 : 요소마다의 이동 경로 추적용 코드
○ 핵심 해결과정 :
①. 핸들러 구현부 : event.target과 event.relatedTarget 값을 출력해보면,
- event.target : 현시점의 마우스 포인터 위에 있는 요소노드 태그 출력
- event.relatedTarget : 변화가 됐다면, 그 전시점의 마우스 포인터 위에있는 요소노드 태그 출력
②. 마찬가지로 , ★부모 Box에 addEventListener() 적용
- 부모Box요소노드.addEventListener('mounseover', 핸들러);
- 부모Box요소노드.addEventListener('mounseout', 핸들러);
const box = document.querySelector('.box');
function currentPosition(e){
console.log(`----------------------------------------`);
console.log('target : ');
console.log(e.target);
console.log('relatedTarget : ');
console.log(e.relatedTarget);
console.log(`----------------------------------------`);
}
box.addEventListener('mouseover',currentPosition );
box.addEventListener('mouseout',currentPosition );
● 개념_4 : mouseover || mouseout VS mouseenter || mouseleave 의 차이
- mouseover || mouseout : 버블링 단계가 일어남 => 부모 Box 내 자식 cell을 인식한다.
- mouseenter || mouseleave : 버들링 단계가 일어나지 않음 => 부모 Box내 자식cell 인식 X
※연습문제 :
● 문제 조건 :
실습 설명
얼마 전 월급이 오른 효준이는 큰맘 먹고 집을 이사했습니다. 비록 전셋집이지만 나름대로 만족스러운 집을 구했어요.
실습 창의 코드는 효준이가 장만한 새로운 집의 평면도를 HTML과 CSS로 구현한 코드입니다. 다만, 코드를 실행해보면 아직 각 공간이 어떤 공간인지는 표시되지 않았어요.
HTML 코드를 좀 더 자세히 살펴보니 몇몇 태그에 data-title 속성에 각 태그가 의미하는 공간이 어떤 공간인지 적혀있습니다.
data-title 속성과 자바스크립트를 활용해서 마우스 커서가 해당 태그 위로 올라가면 data-title 속성의 값이 나타나도록 코드를 완성해 주세요.
세부적인 조건은 다음과 같습니다.
1. showTitle 함수
- ①. showTitle 함수가 호출되면 가장 먼저 조건문을 통해 이벤트 객체의 target 프로퍼티에 담긴 요소에 data-title 속성의 값을 가지고 있는지 확인합니다.
- ②. 조건문이 true일 경우 span 태그 형태의 요소 노드를 생성합니다.
- ③. 이 요소 노드는 'title'이라는 class 값을 가지고 있어야 합니다.
- ④. 이 요소 노드의 내부에 target 프로퍼티에 담긴 요소의 data-title 속성에 담긴 값을 할당해 주세요.
- ⑤. 이 요소 노드를 target 프로퍼티에 담긴 요소의 마지막 자식 요소 노드로 추가해 주세요.
2. removeTitle 함수
- ①. removeTitle 함수가 호출되면 가장 먼저 조건문을 통해 이벤트 객체의 target 프로퍼티에 담긴 요소에 data-title 속성의 값을 가지고 있는지 확인합니다.
- ②. 조건문이 true일 경우 이벤트 객체의 target 프로퍼티에 담긴 요소의 가장 마지막 자식 요소를 제거해 주세요.
3. 이벤트 핸들러 등록하기
- ①. 앞서 만든 두 이벤트 핸들러를 하나의 요소 노드에만 등록해도 각 태그에 이벤트가 동작하도록 해주세요.
- ②. 이벤트 위임을 고려했을 때 어떤 요소 노드에 이벤트 핸들러를 등록하면 좋을지 대상 부분을 수정해 주세요.
- ③. 이벤트 위임을 고려했을 때 각각 타입의 이벤트로 이벤트 핸들러를 등록하면 좋을지 타입 부분을 수정해 주세요.
○ 코드 :
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>효준이네 집</title>
<link rel="stylesheet" href="4.css">
</head>
<body>
<div class="map">
<div class="balcony" data-title="발코니"></div>
<div class="room">
<div class="room-1" data-title="침실">
<div class="door"></div>
<div class="window">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</div>
<div class="room-2" data-title="침실/거실">
<div class="window">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<div class="window window-2">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</div>
</div>
<div class="other">
<div class="bathroom" data-title="욕실">
<div class="door"></div>
<div class="bath"></div>
<div class="bathroom-block">
<div class="sink"></div>
<div class="toilet"></div>
</div>
</div>
<div class="utility-room" data-title="다용도실">
<div class="door"></div>
</div>
<div class="entrance" data-title="현관/입구">
<div class="door"></div>
<div class="wall"></div>
</div>
<div class="kitchen" data-title="주방/식당">
<div class="kitchen-block">
<div class="kitchen-sink"></div>
<div class="stoves">
<div class="stove"></div>
<div class="stove"></div>
</div>
</div>
</div>
</div>
</div>
<script>
</script>
</body>
</html>
● 알아야 할 개념 :
- HTML 코드에서 각 방에 요소노드 안에 "data-title"이라는 속성과 속성값(방의 이름)을 이용함 => dataset프로퍼티로 풀어야함
- 각 요소노드에 data-title 속성 존재여부 판단 : event.target.dataset.속성값명프로퍼티이용
=> if(event.target.dataset.title) {....}
- 노드(태그)에 data-title 속성 추가하는 방법
=> element.textContent = element.dataset.title
● 풀이과정 :
①. showTtile() : //마우스 포인터가 각 방을 가리킬 경우 => 그 방의 이름 출력 메소드
- if조건문 + 요소노드.dataset.속성명 프로퍼티 로 event.target 요소노드에 dataset.속성명값이 있는지 확인
- 있다면, 요소노드 생성 , dataset.속성명 프로퍼티 삽입 : element.textContent = 부모의 dataset.title값
- 그 event.target노드의 자식노드에 삽입 : e.target.append(요소노드) //마지막 노드에 추가시킴
②. removeTtile() : //마우스 포인터가 벗어날 경우 => 그방의 이름 다시 사라지기
: showTtile()에서 span노드를 생성후, 그 해당노드의 자식에 추가하였다. => 그럼 반대로 그 자식 노드를 삭제하기
=> e.target.lastElementChild.remove()
③. ① . ②에 showTitle(), removeTitle() 메소드를 event에 적용
=> 제일 상위 부모Box.appendEventListener('mouseover',showTitle()); //이름 출력은 마우스 포인터가 방에 들어갈 때 이므로, 'mouseover' 에 해당
=> 제일 상위 부모Box.appendEventListener('mouseout',removeTitle()); //이름 출력은 마우스 포인터가 방에나갈때. 이므로, 'mouseout' 에 해당
● 정답 :
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>효준이네 집</title>
<link rel="stylesheet" href="4.css">
</head>
<body>
<div class="map">
<div class="balcony" data-title="발코니"></div>
<div class="room">
<div class="room-1" data-title="침실">
<div class="door"></div>
<div class="window">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</div>
<div class="room-2" data-title="침실/거실">
<div class="window">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<div class="window window-2">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</div>
</div>
<div class="other">
<div class="bathroom" data-title="욕실">
<div class="door"></div>
<div class="bath"></div>
<div class="bathroom-block">
<div class="sink"></div>
<div class="toilet"></div>
</div>
</div>
<div class="utility-room" data-title="다용도실">
<div class="door"></div>
</div>
<div class="entrance" data-title="현관/입구">
<div class="door"></div>
<div class="wall"></div>
</div>
<div class="kitchen" data-title="주방/식당">
<div class="kitchen-block">
<div class="kitchen-sink"></div>
<div class="stoves">
<div class="stove"></div>
<div class="stove"></div>
</div>
</div>
</div>
</div>
</div>
<script>
const map = document.querySelector('.map');
//요소 안에 들어갈 시 , 방의 이름 출력 핸들러
function showTitle(e){
if(e.target.dataset.title)
{
const node = document.createElement('SPAN');
node.classList.add('title');
//속성과 속성값 추가법
node.textContent = e.target.dataset.title;
e.target.append(node);
}
}
//요소 밖으로 포인터 나갌 시 , 방의 이름 출력 x 핸들러
function removeTitle(e){
if(e.target.dataset.title)
{
e.target.lastElementChild.remove();
}
}
//각 핸들러를 동작 event에 따라 부모Box인 map에 적용
map.addEventListener('mouseover',showTitle);
map.addEventListener('mouseout',removeTitle);
</script>
</body>
</html>
'CodeIt_Sprint > JavaScript_중급' 카테고리의 다른 글
(12)JavaScript중급_4_이벤트 활용_Input태그관련 이벤트 (1) | 2024.11.15 |
---|---|
(11)JavaScript중급_4_이벤트 활용_KeyBoard_event (1) | 2024.11.15 |
(9)JavaScript중급_4_이벤트 활용_Mouse_event_1_클릭관련 (0) | 2024.11.15 |
(8)JavaScript중급_3_5_event 객체의 프로퍼티 메소드 : preventDefault() (0) | 2024.11.13 |
(7)JavaScript중급_3_4_이벤트 위임 문제 , 해결방법은 if조건절 + event.contains() 메소드 (5) | 2024.11.13 |