[Codeit boost 1기] 1주차 인터랙티브 자바스크립트

김서윤·2024년 7월 1일
0
post-thumbnail

1주차 인터랙티브 자바스크립트


1️⃣ 인터랙티브 자바스크립트 시작하기

01. 웹 서비스와 JavaScript

→ JavaScript를 통해 웹 서비스를 동작

02. HTML/CSS + JavaScript 맛보기

생략

03~04. id로 태그 선택하기

id는 하나이기 때문에 하나의 요소를 선택하기에 좋음

→ 잘못된 id 선택시 : undefined

const myNumberTag = document.getElementById("myNumber");
const decreaseBtn = document.getElementById("decrease");
const increaseBtn = document.getElementById("increase");

05, 07. class로 태그 선택하기

→ 여러 요소를 선택하기 위해서는 class 선택

→ 잘못된 class 선택시 : undefined

→ ❗️유사 배열 : 여러개의 값을 담고 있는 배열과 형태는 유사하지만, 배열 메소드는 사용할 수 없음

  • (순서는 위에서 아래, 차례대로)
  • index, length 사용
const colorBtns = document.getElementsByClassName("color-btn");

06. 유사 배열(Array-Like Object)이란?

: 배열과 모양은 같지만, 완벽히 배열은 아닌 형태

  1. 숫자 형태의 indexing이 가능
  2. length 프로퍼티 존재
  3. 배열의 기본 메소드 사용 불가
  4. Array.isArray(유사배열)은 false
  • 주의사항: 유사 배열은 다양!

08. 태그 이름으로 태그 선택하기

→ 문서 내에 있는 모든 해당 태그를 선택

const btns = document.getElementsByTagName('button');

09~10. css 선택자로 태그 선택하기

// const myNumberTag = document.getElementById("myNumber");
const myNumberTag = document.querySelector('#myNumber');

// const colorBtns = document.getElementsByClassName("color-btn");
// const colorBtns = document.querySelector(".color-btn");
const colorBtns = document.querySelectorAll(".color-btn");

querySelectorclass의 경우 첫번째 인덱스만 선택됨 ⚠️ 주의 → querySelectorAll

11. 이벤트와 버튼 클릭

// 이벤트(Event)와 버튼 클릭
const btn = document.querySelector("#myBtn");

// 이벤트 핸들링 (Event Handling)
btn.onclick = function () {
  // 이벤트 핸들러 (Event Handler)
  console.log("Hello Codeit!");
};

12. 정답일까?

  • 실습 코드
    const myBtn = document.querySelector('#grade');
    
    myBtn.onclick = function() {
      alert('정답입니다!👏🏻');
    };

13. 종합 정리

메소드의미결과
document.getElementById('id')HTML id속성으로 태그 선택하기id에 해당하는 태그 하나
document.getElementsByClassName('class')HTML class속성으로 태그 선택하기class에 해당하는 태그 모음(HTMLCollection)
document.getElementsByTagName('tag')HTML 태그 이름으로 태그 선택하기tag에 해당하는 태그 모음(HTMLCollection)
document.querySelector('css')css 선택자로 태그 선택하기css 선택자에 해당하는 태그 중 가장 첫번째 태그 하나
document.querySelectorAll('css')css 선택자로 태그 선택하기css 선택자에 해당하는 태그 모음(NodeList)

2️⃣ 브라우저와 자바스크립트

01. 브라우저도 객체다?

window : 전역객체

  • innerWidth
  • innerHeight

02. DOM

→ 문서 객체 모델 (Document Object Model)

console.log : dom에 해당하는 html 태그 출력

title.style.color = ‘red’; → js를 통해 스타일 적용

03. console.dir?

  1. 문자열 표시 형식으로 콘솔에 출력
  2. log 메소드는 파라미터로 전달받은 값을 위주로 출력하는 반면, dir 메소드는 객체의 속성을 좀 더 자세하게 출력
  3. log 메소드는 여러 값을 쉼표로 구분해서 전달하면 전달받은 모든 값을 출력하는 반면, dir 메소드는 여러 값을 전달하더라도 첫 번째 값만 출력
  4. log 메소드는 대상을 HTML 형태로 출력하고, 객체의 속성에 좀 더 중점을 둔 dir 메소드는 대상을 객체 형태로 출력

콘솔에서 값 자체를 확인하고 싶다면 log메소드를, 객체의 속성들을 살펴보고 싶다면 dir 메소드를 활용

04~07. DOM 트리

→ 부모 노드, 자식 노드, 형제 노드 / 요소 노드, 텍스트 노드, 잎 노드, 코멘트 노드, 문서 노드

: 텍스트 노드는 요소 노드의 자식 노드! 자식 노드를 가질 수 없다.

const myTag = document.querySelector('#content');

console.log(myTag);
//console.log(myTag.parentElement.nextElementSibling);

// 형제 요소 노드
console.log(myTag.previousElementSibling);
console.log(myTag.nextElementSibling);

// 부모 요소 노드
console.log(myTag.parentElement);

// 자식 요소 노드
console.log(myTag.childern[1]);
console.log(myTag.firstElementChild);
console.log(myTag.lastElementChild);

요소 노드에 대한 이동 프로퍼티

프로퍼티유형결과
element.children자식 요소 노드element의 자식 요소 모음(HTMLCollection)
element.firstElementChild자식 요소 노드element의 첫 번째 자식 요소 하나
element.lastElementChild자식 요소 노드element의 마지막 자식 요소 하나
element.parentElement부모 요소 노드element의 부모 요소 하나
element.previousElementSibling형제 요소 노드element의 이전(previous) 혹은 좌측(left)에 있는 요소 하나
element.nextElementSibling형제 요소 노드element의 다음(next) 혹은 우측(right)에 있는 요소 하나

모든 노드에 대한 이동 프로퍼티

프로퍼티유형결과
node.childNodes자식 노드node의 자식 노드 모음(NodeList)
node.firstChild자식 노드node의 첫 번째 자식 노드 하나
node.lastChild자식 노드node의 마지막 자식 노드 하나
node.parentNode부모 노드node의 부모 요소 하나
node.previousSibling형제 노드node의 이전(previous) 혹은 좌측(left)에 있는 노드 하나
node.nextSibling형제 노드node의 다음(next) 혹은 우측(right)에 있는 노드 하나

08~10. 요소 노드 프로퍼티

// 요소 노드 주요 프로퍼티
const myTag = document.querySelector('#list-1');

// innerHTML
console.log(myTag.innerHTML);
myTag.innerHTML = '<li>Exotic</li>';

// outerHTML -> 요소 자체가 교체 (원래 요소 삭제)
console.log(myTag.outerHTML);
myTag.outerHTML = '<ul id="new-list"><li>Exotic</li></ul>';

// textContent -> innerHTML과 마찬가지로 수정, only 텍스트만 다룸(특수문자도 텍스트로)
console.log(myTag.textContent);
myTag.textContent = 'new text!';
  1. element.innerHTML
  • 요소 노드 내부의 HTML 코드를 문자열로 리턴해 줍니다. (내부에 있는 줄 바꿈이나 들여쓰기 모두 포함합니다.)
  1. element.outerHTML
  • 요소 노드 자체의 전체적인 HTML 코드를 문자열로 리턴해줍니다. (내부에 있는 줄 바꿈이나 들여쓰기 모두 포함합니다.)
  1. element.textContent
  • 요소 안의 내용들 중에서 HTML 태그 부분은 제외하고 텍스트만 가져옵니다. (내부에 있는 줄 바꿈이나 들여쓰기 모두 포함합니다.)

11. 요소 노드 추가하기

// 요소 노드 추가하기
const tomorrow = document.querySelector('#tomorrow');

// 1. 요소 노드 만들기: document.createElement('태그이름');
const first = document.createElement('li');

// 2. 요소 노드 꾸미기: textContent, innerHTML, ...
first.textContent('처음');

// 3. 요소 노드 추가하기: NODE.prepend, append, after, before
tomorrow.prepend(first); // 처음 (한번에 순서대로 추가)
tomorrow.prepend(append); // 마지막
tomorrow.prepend(after); // 이전 (한번에 순서대로 추가)
tomorrow.prepend(before); // 다음

12. 노드 삭제와 이동하기

// 노드 삭제와 이동
const today = document.querySelector('#today');
const tomorrow = document.querySelector('#tomorrow');

// 노드 삭제하기: Node.remove();
tomorrow.remove();
today.children[2].remove();

// 노드 이동하기: prepend, append, after, before
today.append(tomorrow.children[1]);
tomorrow.children[1].after(today.children[1]);
tomorrow.lastElementChild.after(today.children[1]);

13. 오늘 꼭 해야할 일!

  • 실습 코드
    const toDoList = document.querySelector('#to-do-list');
    
    function addNewTodo(text) {
      const li = document.createElement("li");
      li.textContent = text;
      toDoList.append(li);
    }
    
    // 테스트 코드
    addNewTodo('자바스크립트 공부하기');
    addNewTodo('고양이 화장실 청소하기');
    addNewTodo('고양이 장난감 쇼핑하기');

14~15. HTML 속성 다루기

// HTML 속성
const tomorrow = document.querySelector('#tomorrow');
const item = tomorrow.firstElementChild;
const link = item.firstElementChild;

// id 속성
console.log(tomorrow.id);

// class 속성
console.log(item.className);

// href 속성
console.log(link.href);
console.log(tomorrow.href);

// elem.getAttribute('속성'): 속성에 접근하기
console.log(tomorrow.getAttribute('href'));
console.log(item.getAttribute('class'));

// elem.setAttribute('속성', '값'): 속성에 추가(수정)하기
tomorrow.setAttribute('class', 'list');
link.setAttribute('href', 'https://www.codeit.kr');

// elem.removeAttribute('속성'): 속성 제거하기
tomorrow.removeAttribute('href');
tomorrow.removeAttribute('class');

16~17. 스타일 다루기

// 스타일 다루기
const today = document.querySelector('#today');
const tomorrow = document.querySelector('#tomorrow');

// style 프로퍼티
today.children[0].style.textDecoration = 'line-through';
today.children[0].style.backgroundColor = '#DDDDDD';

// elem.className
today.children[1].className = 'done';

// elem.classList: add, remove, toggle
const item = tomorrow.children[1];
item.classList.add('done', 'other');
item.classList.remove('done');
item.classList.remove('toggle'); // 없으면 추가, 있으면 제거, 여러개 불가(클래스 1개만을 다룸)

18. 비표준 속성 다루기

  1. 선택자로 활용

가장 간단하게는 아래와 같이 querySelector로 태그를 선택할 때 css 선택자를 활용해서 태그를 선택하는 데에 활용 가능

const fields = document.querySelectorAll('[field]');
console.log(fields);
  1. 값을 표시할 태그를 구분할 때 활용

비표준 속성은 객체 형태의 데이터가 있을 때, 각 프로퍼티 값들이 들어갈 태그를 구분하는데 활용 가능


const fields = document.querySelectorAll('[field]');
const task = {
  title: '코드 에디터 개발',
  manager: 'CastleRing, Raccoon Lee',
  status: '',
};

for (let tag of fields) {
  const field = tag.getAttribute('field');
  tag.textContent = task[field];
}
  1. 스타일이나 데이터 변경에 활용

getAttribute 메소드를 활용해서 속성값을 가져오고, setAttribute 메소드를 활용해서 속성값을 설정해주는 원리로 이벤트를 통해 실시간으로 스타일을 변경하거나 데이터를 변경하는데 활용 가능

때로는 class를 다루는 것보다 setAttribute로 비표준 속성을 변경하는게 스타일을 다루기에 오히려 편리한 경우도 존재

const fields = document.querySelectorAll('[field]');
const task = {
  title: '코드 에디터 개발',
  manager: 'CastleRing, Raccoon Lee',
  status: '',
};

for (let tag of fields) {
  const field = tag.getAttribute('field');
  tag.textContent = task[field];
}

const btns = document.querySelectorAll('.btn');
for (let btn of btns) {
  const status = btn.getAttribute('status');
  btn.onclick = function () {
    fields[2].textContent = status;
    fields[2].setAttribute('status', status);
  };
}

좀 더 안전하게, dataset 프로퍼티

: data-로 시작하는 속성은 모두 dataset이라는 프로퍼티에 저장

예. data-status라는 속성이 있다면, element.dataset.status라는 프로퍼티에 접근해서 그 값을 가져옴

const fields = document.querySelectorAll('[data-field]');
const task = {
  title: '코드 에디터 개발',
  manager: 'CastleRing, Raccoon Lee',
  status: '',
};

for (let tag of fields) {
  const field = tag.dataset.field;
  tag.textContent = task[field];
}

const btns = document.querySelectorAll('.btn');
for (let btn of btns) {
  const status = btn.dataset.status;
  btn.onclick = function () {
    fields[2].textContent = status;
    fields[2].dataset.status = status;
  };
}

3️⃣ 이벤트 살펴보기

01~03. 이벤트 핸들러 등록하기

// 이벤트 핸들러 등록하기
const btn = document.querySelector("#myBtn");

function event1() {
	console.log('Hi Codeit!');
}

function event2() {
	console.log('Hi again!');
}

// onclick은 하나의 것만 가능 (덮어씌워짐)
// elem.addEventListener(event, handler)
btn.addEventListener('click', event1);
btn.addEventListener('click', event2);

// elem.removeEventListener(event, handler)
btn.removeEventListener('click', event2);

마우스 이벤트

이벤트 타입설명
mousedown마우스 버튼을 누르는 순간
mouseup마우스 버튼을 눌렀다 떼는 순간
click왼쪽 버튼을 클릭한 순간
dblclick왼쪽 버튼을 빠르게 두 번 클릭한 순간
contextmenu오른쪽 버튼을 클릭한 순간
mousemove마우스를 움직이는 순간
mouseover마우스 포인터가 요소 위로 올라온 순간
mouseout마우스 포인터가 요소에서 벗어나는 순간
mouseenter마우스 포인터가 요소 위로 올라온 순간 (버블링이 일어나지 않음)
mouseleave마우스 포인터가 요소에서 벗어나는 순간 (버블링이 일어나지 않음)

키보드 이벤트

이벤트 타입설명
keydown키보드의 버튼을 누르는 순간
keypress키보드의 버튼을 누르는 순간 ('a', '5' 등 출력이 가능한 키에서만 동작하며, Shift, Esc 등의 키에는 반응하지 않음)
keyup키보드의 버튼을 눌렀다 떼는 순간

포커스 이벤트

이벤트 타입설명
focusin요소에 포커스가 되는 순간
focusout요소로부터 포커스가 빠져나가는 순간
focus요소에 포커스가 되는 순간 (버블링이 일어나지 않음)
blur요소로부터 포커스가 빠져나가는 순간 (버블링이 일어나지 않음)

입력 이벤트

이벤트 타입설명
change입력된 값이 바뀌는 순간
input값이 입력되는 순간
select입력 양식의 하나가 선택되는 순간
submit폼을 전송하는 순간

스크롤 이벤트

이벤트 타입설명
scroll스크롤 바가 움직일 때

윈도우 창 이벤트

이벤트 타입설명
resize윈도우 사이즈를 움직일 때 발생

04~05. 이벤트 객체 (프로퍼티)

// 이벤트 객체 (Event Object)
const myInput = document.querySelector("#myInput");
const myBtn = document.querySelector("#myBtn");

function printEvent(event) {
  console.log(event);
  event.target.style.color = 'red';
}

myInput.addEventListener("keydown", printEvent);
myBtn.addEventListener("click", printEvent);
  1. 공통 프로퍼티

아래의 프로퍼티들은 이벤트 타입과 상관없이 모든 이벤트 객체들이 공통적으로 가지고 있는 프로퍼티

프로퍼티설명
type이벤트 이름 ('click', 'mouseup', 'keydown' 등)
target이벤트가 발생한 요소
currentTarget이벤트 핸들러가 등록된 요소
timeStamp이벤트 발생 시각(페이지가 로드된 이후부터 경과한 밀리초)
bubbles버블링 단계인지를 판단하는 값
  1. 마우스 이벤트

마우스와 관련된 이벤트의 경우에는 아래와 같은 이벤트 객체의 프로퍼티들

프로퍼티설명
button누른 마우스의 버튼 (0: 왼쪽, 1: 가운데(휠), 2: 오른쪽)
clientX, clientY마우스 커서의 브라우저 표시 영역에서의 위치
pageX, pageY마우스 커서의 문서 영역에서의 위치
offsetX, offsetY마우스 커서의 이벤트 발생한 요소에서의 위치
screenX, screenY마우스 커서의 모니터 화면 영역에서의 위치
altKey이벤트가 발생할 때 alt키를 눌렀는지
ctrlKey이벤트가 발생할 때 ctrl키를 눌렀는지
shiftKey이벤트가 발생할 때 shift키를 눌렀는지
metaKey이벤트가 발생할 때 meta키를 눌렀는지 (window는 window키, mac은 cmd키)
  1. 키보드 이벤트

키보드와 관련된 이벤트의 경우에는 아래와 같은 이벤트 객체의 프로퍼티들

프로퍼티설명
key누른 키가 가지고 있는 값
code누른 키의 물리적인 위치
altKey이벤트가 발생할 때 alt키를 눌렀는지
ctrlKey이벤트가 발생할 때 ctrl키를 눌렀는지
shiftKey이벤트가 발생할 때 shift키를 눌렀는지
metaKey이벤트가 발생할 때 meta키를 눌렀는지 (window는 window키, mac은 cmd키)

06. 완료한 일 체크하기!

  • 실습 코드
    const toDoList = document.querySelector('#to-do-list');
    const items = toDoList.children;
    
    // 1. updateToDo 함수를 완성해 주세요
    function updateToDo(event) {
      event.target.classList.toggle('done');
    }
    
    // 2. 반복문을 활용해서 각 li태그에 이벤트 핸들러를 등록해 주세요
    for (let item of items) {
      item.addEventListener('click', updateToDo);
    }
    
    // 테스트 코드
    items[2].removeEventListener('click', updateToDo);

07, 09. 이벤트 버블링

→ 부모 요소(최상단까지)의 핸들러도 동작

// 이벤트 버블링 (Event Bubbling)
const content = document.querySelector("#content");
const title = document.querySelector("#title");
const list = document.querySelector("#list");
const items = document.querySelectorAll(".item");

content.addEventListener("click", function () {
  console.log("content Event");
});

title.addEventListener("click", function () {
  console.log("title Event");
});

list.addEventListener("click", function () {
  console.log("list Event");
});

for (let item of items) {
  item.addEventListener("click", function () {
    console.log("item Event");
  });
}

currentTarget은 이벤트가 실제로 실행되는 것을 담고 있음

e.stopPropagation(); : 버블링을 막는 코드, 지양

08. 캡쳐링

  1. 캡처링 단계: 이벤트가 하위 요소로 전파되는 단계

  2. 타깃 단계: 이벤트가 실제 타깃 요소에 전달되는 단계

    타깃 단계는 이벤트 객체의 target 프로퍼티가 되는 요소에 등록되어있던 이벤트 핸들러가 동작하는 단계

    → 쉽게 생각해서 가장 처음 이벤트 핸들러가 동작하게 되는 순간

  3. 버블링 단계: 이벤트가 상위 요소로 전파되는 단계

📌 캡쳐링이벤트가 발생하면 가장 먼저, 그리고 버블링의 반대 방향으로 진행되는 이벤트 전파 방식

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8">
    <title>Codeit Acid Rain</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <div>DIV
      <ul>UL
        <li>LI</li>
      </ul>
    </div>  
    <script>
      for (let elem of document.querySelectorAll('*')) {
        elem.addEventListener("click", e => alert(`캡쳐링 단계: ${elem.tagName}`), true);
        elem.addEventListener("click", e => alert(`버블링 단계: ${elem.tagName}`));
      }
    </script>
  </body>
</html>

10. 이벤트 위임

→ 자식 요소의 이벤트를 부모 요소에도 위임 (반대도 포함) : 버블링 활용

// 이벤트 위임 (Event Delegation)
const list = document.querySelector("#list");

list.addEventListener("click", function (e) {
  // if (e.target.tagName === 'LI')
  if (e.target.classList.contains("item")) {
    e.target.classList.toggle("done");
  }
});

const li = document.createElement("li");
li.classList.add("item");
li.textContent = "일기 쓰기";
list.append(li);

11. 효율적으로 완료한 일 체크하기!

  • 실습 코드
    const toDoList = document.querySelector('#to-do-list');
    
    // 1. updateToDo 함수를 완성해 주세요
    function updateToDo(event) {
      if (event.target.classList.contains('item')) {
        event.target.classList.toggle('done');
      }
    }
    
    // 2. 각 li 태그가 아닌 하나의 태그에만 이벤트 핸들러를 등록해 주세요
    toDoList.addEventListener('click', updateToDo);
    
    // 테스트 코드
    const newToDo = document.createElement('li');
    newToDo.textContent = '가계부 정리하기';
    newToDo.classList.add('item');
    toDoList.append(newToDo);
    
    toDoList.children[2].addEventListener('click', function(e) {e.stopPropagation()});

12~13. 브라우저의 기본 동작

// 브라우저의 기본 동작
const link = document.querySelector("#link");
const checkbox = document.querySelector("#checkbox");
const input = document.querySelector("#input");
const text = document.querySelector("#text");

// event.preventDefault
link.addEventListener("click", function (e) {
  e.preventDefault();
  alert("지금은 이동할 수 없습니다.");
});

input.addEventListener("keydown", function (e) {
  if (!checkbox.checked) {
    e.preventDefault();
    alert("체크박스를 먼저 클릭해 주세요.");
  }
});

document.addEventListener("contextmenu", function (e) {
  e.preventDefault();
  alert("마우스 오른쪽 클릭은 사용할 수 없습니다.");
});

4️⃣ 다양한 이벤트 알아보기

01. 마우스 버튼 이벤트

→ 우클릭의 경우 운영체제별로 실행 순서가 변경될 수 있음

[마우스 버튼 이벤트]

  • MouseEvent.button
    • 0: 마우스 왼쪽 버튼
    • 1: 마우스 휠
    • 2: 마우스 오른쪽 버튼
  • MouseEvent.type
    • click: 마우스 왼쪽 버튼을 눌렀을 때
    • contextmenu: 마우스 오른쪽 버튼을 눌렀을 때
    • dblclick: 동일한 위치에서 빠르게 두번 click할 때
    • mousedown: 마우스 버튼을 누른 순간
    • mouseup: 마우스 버튼을 눌렀다 뗀 순간

02. 청기 올려?! 백기 올려?!

  • 실습 코드
    const flagBlue = document.querySelector('.flag-blue');
    const flagWhite = document.querySelector('.flag-white');
    
    function reset() {
      document.querySelector('.up').classList.remove('up');
    }
    
    // 1. flagUp 함수를 완성해 주세요
    function flagUp(e) {
      if (e.button === 0) {
        flagBlue.classList.add('up');
      } else if (e.button === 2) {
        flagWhite.classList.add('up');
      }
    
      // 500 밀리초 뒤에 reset함수를 실행
      setTimeout(reset, 500);
    }
    
    // 2. 마우스 오른쪽 버튼 클릭시 나타나는 메뉴창을 막아주세요
    document.addEventListener('contextmenu', function (event) {
      event.preventDefault();
    });
    
    // 테스트 코드
    document.addEventListener('mousedown', flagUp);

03, 05. 마우스 이동 이벤트

[마우스 이동 이벤트]

  • MouseEvent.type
    • mousemove: 마우스 포인터가 이동할 때
    • mouseover: 마우스 포인터가 요소 밖에서 안으로 이동할 때
    • mouseout: 마우스 포인터가 요소 안에서 밖으로 이동할 때
  • MouseEvent.clientX, clientY : 화면에 표시되는 창 기준 마우스 포인터 위치
  • MouseEvent.pageX, pageY : 웹 문서 전체 기준 마우스 포인터 위치
  • MouseEvent.offsetX, offsetY : 이벤트가 발생한 요소 기준 마우스 포인터 위치
const box1 = document.querySelector('#box1');

function onMouseMove(e) {
  console.log(`client: (${e.clientX}, ${e.clientY})`);
  console.log(`page: (${e.pageX}, ${e.pageY})`);
  console.log(`offset: (${e.offsetX}, ${e.offsetY})`);
  console.log('------------------------------------');
}

box1.addEventListener('mousemove', onMouseMove);
  • MouseEvent.target : 이벤트가 발생한 요소
  • MouseEvent.relatedTarget : 이벤트가 발생하기 직전(또는 직후)에 마우스가 위치해 있던 요소
const box2 = document.querySelector('#box2');

function printEventData(e) {
  console.log('event:', e.type);
  console.log('target:', e.target);
  console.log('relatedTarget:', e.relatedTarget);
  console.log('------------------------------------');
  if (e.target.classList.contains('cell')) {
    e.target.classList.toggle('on');
  }
}

box2.addEventListener('mouseover', printEventData);
box2.addEventListener('mouseout', printEventData);

04. client, page, offset 차이

  1. clientX, clientY
  • client 프로퍼티는 말 그대로 클라이언트 영역 내에서 마우스의 좌표 정보
  • 클라이언트 영역이란 이벤트가 발생한 순간에 브라우저가 콘텐츠를 표시할 수 있는 영역
  • clientX : 브라우저가 표시하는 화면 내에서 마우스의 X좌표 위치
    clientY : 브라우저가 표시하는 화면 내에서 마우스의 Y좌표 위
  • client 값은 그 순간 보여지는 화면을 기준으로 계산하기 때문에 스크롤 위치와는 무관하게 항상 보여지는 화면의 좌측 상단의 모서리 위치를 (0, 0)으로 계산
  1. offsetX, offsetY
  • offset 프로퍼티는 이벤트가 발생한 target이 기준
  • offsetX : 이벤트가 발생한 target 내에서 마우스의 X좌표 위치
    offsetY : 이벤트가 발생한 target 내에서 마우스의 Y좌표 위치
  • offset 값도 이벤트가 발생한 대상을 기준으로 계산하기 때문에 스크롤 위치와는 무관하게 항상 대상의 좌측 상단의 모서리 위치를 (0, 0)으로 계산
  1. pageX, pageY
  • page 프로퍼티는 전체 문서를 기준으로 마우스 좌표 정보
  • 스크롤로 인해서 보이지 않게된 화면의 영역까지 포함해서 측정한다는 점이 앞의 두 프로퍼티와의 차이점
  • pageX : 전체 문서 내에서 마우스의 X좌표 위치
    pageY : 전체 문서 내에서 마우스의 Y좌표 위치

스크린샷 2024-06-30 오전 10.45.35.png

06. mouseenter / mouseleave

  1. 버블링이 일어나지 않는다.

    mouseentermouseleave버블링이 일어나지 않음

  2. 자식 요소의 영역을 계산하지 않는다.

    mouseentermouseleave자식 요소의 영역을 계산하지 않음

이벤트가 자식 요소에 영향끼치는지가 둘의 가장 큰 차이

  • 이벤트 핸들러가 자식 요소에까지 영향을 끼치게 하고싶은 경우에는 mouseover/mouseout
  • 자식 요소에는 영향을 끼치지 않고 해당 요소에만 이벤트 핸들러를 다루고자 한다면 mouseenter/mouseleave를 활용

07. 효준이네 집

  • 실습 코드
    function showTitle(e) {
      if (e.target.dataset.title) {
        const span = document.createElement(<'span');
        span.classList.add('title');
        span.textContent = e.target.dataset.title;
        e.target.append(span);
      }
    }
    
    function removeTitle(e) {
      if (e.target.dataset.title) {
        e.target.lastElementChild.remove();
      }
    }
    
    const map = document.querySelector('.map');
    map.addEventListener('mouseover', showTitle);
    map.addEventListener('mouseout', removeTitle);

08. 키보드 이벤트

[키보드 이벤트]

  • KeyboardEvent.type
    • keydown: 키보드 버튼을 누른 순간 (권장)
    • keypress: 키보드 버튼을 누른 순간 (지양)
    • keyup: 키보드 버튼을 눌렀다 뗀 순간
  • KeyboardEvent.key : 이벤트가 발생한 버튼의 값
  • KeyboardEvent.code : 이벤트가 발생한 버튼의 키보드에서 물리적인 위치

09. 똑Talk한 Enter키!

  • 실습 코드
    const chatBox = document.querySelector('#chat-box');
    const input = document.querySelector('#input');
    const send = document.querySelector('#send');
    
    function sendMyText() {
      const newMessage = input.value;
      if (newMessage) {
        const div = document.createElement('div');
        div.classList.add('bubble', 'my-bubble');
        div.innerText = newMessage;
        chatBox.append(div);
      } else {
        alert('메시지를 입력하세요...');
      }
    
      input.value = '';
    }
    
    send.addEventListener('click', sendMyText);
    
    function sendMyTextByEnter (e) {
      if (e.key === 'Enter' && !e.shiftKey) {
        sendMyText();
        e.preventDefault();
      }
    }
    
    input.addEventListener('keypress', sendMyTextByEnter);

10. input 태그 다루기

[input 태그 다루기]

  • 포커스 이벤트
    • focusin: 요소에 포커스가 되었을 때
    • focusout: 요소에 포커스가 빠져나갈 때
    • focus: 요소에 포커스가 되었을 때 (버블링 X)
    • blur: 요소에 포커스가 빠져나갈 때 (버블링 X)

11. 코드잇 산성비

  • 실습 코드
    const input = document.querySelector('#input');
    
    function checker() {
      const words = document.querySelectorAll('.word');
      if (words.length === 0) {
        alert('Success!👏🏻');
        if(confirm('retry?')) {
          window.location.reload();
        }
      }
    }
    
    function removeWord() {
      const word = document.querySelector(`[data-word="${input.value}"]`);
      if (word) {
        word.remove();
        checker();
      }
    
      input.value = '';
    }
    
    input.addEventListener('change', removeWord);

12. 스크롤 이벤트

// Scroll 이벤트
function printEvent(e) {
  const STANDARD = 30;

  const nav = document.querySelector("#nav");
  const toTop = document.querySelector("#to-top");

  // 스크롤이 30px을 넘었을 때
  if (window.scrollY > STANDARD) {
    nav.classList.add("shadow");
    toTop.classList.add("show");
  } else {
    nav.classList.remove("shadow");
    toTop.classList.remove("show");
  }
}

window.addEventListener("scroll", printEvent);

0개의 댓글

관련 채용 정보