Search

자바스크립트

인터렉티브 자바스크립트

시작하기

id로 태그 선택하기

document.getElementById("myNumber")

class로 태그 선택하기

document.getElementsByClassName('color-btn')
선택되있는 형태 → HTMLCollection : 배열의 형태인 '유사배열'
배열의 메소드는 사용할 수 없다.
하지만 대괄호 표기법으로 인덱스에 접근한다거나, length 프로퍼티를 사용할 수도 있고
for of 문을 쓸 수 있다.
깊이와는 상관없이 위에서부터 차례대로 읽어들인다.

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

const btns = document.getElementsByTagName('button' ) → 버튼을 선택하는 것이다.

CSS 선택자로 태그 선택하기

const myTag = document.querySelector('#myNumber') → CSS 선택자를 문자열로 전달해주면 된다. 이건 id를 받는 것
const myTag = document.querySelector('.color-btn') →이렇게 하면 여러 클래스의 태그들 중에 맨 첫번째 태그만 받는다.
const myTag = document.querySelectorAll('.color-btn') →클래스를 나타내는 선택자인데 이걸 해보면, NodeList를 출력한다. HTMLCollection으로 반환되는 getElementsByClassName이랑 약간 다르지만 형태는 똑같다

이벤트와 버튼 클릭

마우스를 움직이거나 키보드, 페이지를 스크롤하는 것도 다 이벤트이다.
이벤트에 함수를 할당해서 행동을 하도록 함수를 짜면 된다. 이거를 이벤트 핸들러라고 부른다.
HTML에서 inline으로 집어넣을 수도 있다.

브라우저와 자바스크립트

자바스크립트는 모든 것이 객체다
console.log(window);
window 객체는 브라우저의 창을 대변한다. 객체 안에 있는 프로퍼티를 활용하면, 브라우저를 제어하거나 정보를 얻을 수 있다.
innerWidth, innerHeight → 창의 크기를 돌려주는 property
window 객체의 프로퍼티 → Document객체와 Console의 객체
Window 객체는 자바스크립트의 최상단 객체이다.

DOM

문서 객체 모델
DOM → 웹 페이지에 나타나는 html문서 전체를 객체로 표현한거다.
document 객체가 웹 문서의 최상단 객체이다. Document객체를 활용하면 웹 페이지 내에 뭐든지 수정하고 만들어낼 수 있다.
HTML 태그의 구조를 살펴보면 태그 안에 태그 형태의 계층 구조, 부모 태그와 자식 태그로 나타낸다.
window → document → DOM Tree
각 객체를 노드라고 표현한다. 부모 노드와 자식 노드, 형제 노드의 관계로 이어진다.
Node Type → 태그를 표현하는 노드: Element Node , 문자를 나타내는 노드: Text Node
Text Node → 요소 노드의 자식 노드가 되고, 자식 노드를 가질 수 없다. 나무의 잎사귀에 비유해서 leaf Node라고 얘기한다.
코멘트를 표현하는 코멘트 노드
문서를 표현하는 문서 노드 등등
대부분의 DOM 트리는 요소노드와 텍스트 노드로 이뤄진다.

DOM 트리 여행하기

선택하고 싶은 노드를 선택할 줄 알아야한다.
document.querySelector('#content')
Dom 트리의 부모 자식 형제 관계를 이용해서 태그를 선택해보자
자식 노드 선택하기
myTag.children → HTMLCollection이 출력된다. 대괄호 표기법으로 선택하는 것도 가능하다
myTag.firstElementChild → 자식들 중 첫째 자식
myTag.lastElementChild → 자식들 중 마지막 자식
부모 노드 선택하기
myTag.parentElement → 부모 태그를 선택하자
형제 노드
myTag.previousElementSibling → 이전 형제
myTag.nextElementSibling → 다음 형제
프로퍼티
유형
결과
자식 요소 노드
element의 첫 번째 자식 요소 하나
자식 요소 노드
element의 마지막 자식 요소 하나
부모 요소 노드
element의 부모 요소 하나
형제 요소 노드
element의 이전(previous) 혹은 좌측(left)에 있는 요소 하나
형제 요소 노드
element의 다음(next) 혹은 우측(right)에 있는 요소 하나
프로퍼티
유형
결과
자식 노드
node의 자식 노드 모음(NodeList)
자식 노드
node의 첫 번째 자식 노드 하나
자식 노드
node의 마지막 자식 노드 하나
부모 노드
node의 부모 요소 하나
형제 노드
node의 이전(previous) 혹은 좌측(left)에 있는 노드 하나
형제 노드
node의 다음(next) 혹은 우측(right)에 있는 노드 하

Element Node property

innerHTML
태그와 태그 사이의 줄바꿈이나 들여쓰기도 모두 포함된다.
요소 안의 property를 수정할 때 사용한다.
얘도 마찬가지로 내부에 있던 값을 아예 새로운 값으로 교체한다.
outerHTML
해당 태그가 시작되는 지점부터 끝나는 지점까지 포함한다.
outerHTML에 새로운 html코드를 할당할 수 있는데, outerHTML의 특성상
요소 자체가 교체된다. 처음 요소는 사라진다.
textContent
innterHTML과 비슷하다. 요소 안에 있는 내용들 중, html을 제외한 텍스트만을 들고온다.
HTML코드처럼 작성하더라도, 특수문자도 그냥 텍스트로 출력한다. 사용자의 입력값을 웹페이지에 반영해야할 때, textContent로 추가하면 원하지 않은 HTML코드가 웹페이제 추가되는 걸 방지할 수 있다.

요소 노드 추가하기

today.innerHTML = '<li> 처음<li>' + today.innerHTML; //요소 노드 만들기 const first = document.createElement('li'); //요소 노드 꾸미기 first.textContent = '처음'; //집어넣기 tomorrow.prepend(first); //맨 처음 자식으로 노드에 집어넣기 append(last);// 맨마지막 자식으로 노드에 집어넣기 before(prev) // 메소드를 호출한 요소의 첫번째(맨 앞) 형제노드로 추가한다. after(next) // 메소드를 호출한 요소의 마지막(맨 뒤) 형제노드로 추가한다.
JavaScript
복사

노드 삭제와 이동하기

//노드 삭제 tomorrow.remove(); today.children[2].remove(); //노드 이동 prepend, append,before, after today.append(tomorrow.children[1]) // 기존에 있는 거라면 그냥 이동한다.
JavaScript
복사

HTML 속성 다루기

elem.getAttribute('속성') → HTML의 속성에 접근할 수 있다.
elem.setAttribute('속성','값') → 기존 속성이면 수정되고, 없는거면 새로 생긴다.
eleme.removeAttribute('속성') → 해당 속성을 제거할 수 있다.
속성 이름들은 대소문자를 구분하지 않는다.

Style 다루기

속성중에 여러 단어를 조합해서 만든거는 Camel표기법을 따라야한다.
style프로퍼티를 사용하면, 인라인으로 들어간다.
style우선순위가 높아지는 문제가 있고, 비슷한 코드를 불필요하게 많이 작성해야한다.
태그의 클래스를 변경하는 것이 권장되는 방식이다.
className프로퍼티를 확인하는 것이다.
스타일 시트에 형식에 대한 스타일을 작성해놓고, 클래스를 변경함으로써 디자인을 바꾼다.
이 때 class를 그대로 추가하고 싶으면...?
classList → 클래스의 속성값을 유사배열로 다루는 것이다. 클래스를 하나씩 다룬다.
add, remove, toggle을 다루는 메소드도 쓸 수 있다.
add → 클래스를 추가하는 것, 쉼표로 구분해서 여러개의 파라미터로 전달할 수 있다.
remove → 클래스를 제거하는 메소드, 파라미터로 클래스 이름을 전달하면 클래스가 삭제된다. add와 마찬가지로 여러 개를 전달하면 여러개가 삭제된다.
toggle → 있으면 제거하고 없으면 추가하는 메소드이다. toggle은 여러개를 전달한다고 여러 개가 되진 않는다. 두 번째 파라미터는 boolean이고 , True → add , False → remove 이다.
기본적으로 style프로퍼티를 활용해서 수정하기보다.
css파일에 원하는 스타일의 클래스를 지정해놓고, js에서는 클래스 이름을 바꾸는 것이 통상적이다.

이벤트 핸들러 등록하기

onclick 프로퍼티를 활용하지 않고 이벤트 핸들러를 등록하기
btn.addEventListener('event,handler)
하나의 요소에 여러 개의 이벤트 핸들러를 등록할 수 있다.
element.removeEventListner(event, handler)
해당 이벤트에 대해서 handler를 삭제한다.
이벤트를 삭제할 때, 등록할 때 사용했던 핸들러를 그대로 전달해야한다.
이벤트를 삭제할 필요가 있다면, 반드시 등록할 때 함수 이름을 지정해서 전달해야한다. 이벤트 핸들러 부분에는 함수 이름을 전달하면 된다.
소괄호를 붙여서 하면 함수를 호출한 리턴 값을 반환해서 파라미터로 전달한다.

이벤트 객체

'keydown' → 키를 누를 때
'click' → 마우스를 클릭할 때
이벤트가 발생하면 이벤트 객체가 발생한다.
이벤트 핸들러의 첫번째 파라미터에는 이벤트 객체가 전달된다.
이벤트 객체의 공통적인 프로퍼티 → type & target
Type : 발생한 이벤트의 type을 담고 있다
target : 해당 이벤트가 발생한 요소가 담겨있다.
event.target.style.color = 'red'라고 하면 빨간색으로 바뀐다.

이벤트 버블링

요소 하나를 누르면 같은 타입의 이벤트 타입에 한하여 부모 요소를 타고 거슬러가서 모든 이벤트를 만들어낸다.
Target Property → 이벤트 버블링이 생겨도 Target이 바뀌지 않는다. 처음 이벤트가 발생한 시작점을 담고 있다.
만약 실행중에 핸들러가 등록된 요소에 접근하고 싶으면 currentTarget →이벤트 핸들러가 동작하는 요소를 출력한다.
이벤트 객체의 stopPropagation() → e.stopPropagation(), 버블링을 막을 수 있다.
버블링이 막혀있는 부분이 있으면 좀 그렇다

캡처링

addEventListener("click",function, true); → 캡처링 단계에 이벤트 핸들러를 동작시킨다.
캡처링 → 타겟 → 버블링 순서

이벤트 위임

새로운 요소를 추가할 때마다, 이벤트 핸들러를 추가해야한다.
버블링 개념에 따르면, 부모요소가 자식 요소에서 발생한 이벤트를 감지할 수 있다.
아이템 각각에 이벤트 핸들러를 등록하는게 아니라, 부모요소에 등록함으로써 추가할 때마다 이벤트 핸들러를 추가 하지 않아도 된다.
이거를 이벤트 위임이라고 한다.
부모 요소를 클릭해도 이벤트가 뜬다.
타겟의 프로퍼티 (tagName 또는 classList.contains('items') 등등 해당 요소를 구분해줄 수 있는 프로퍼티나 메소드를 찾아야한다.)
이벤트 위임을 할 때, 자식 요소에서'만' 이벤트 핸들러가 작동하게끔 잘 짜줘야한다.

브라우저의 기본 동작

a tag → href 주소로 이동
input → check박스가 토글
input → textbox가 focus된다.
브라우저 자체의 기본 동작이 다 있다.
event.preventDefault()
마우스우클릭 → contextmenu라는 타입으로 이벤트가 발생한다.
텍스트 위에서는 오른쪽 클릭이 막힌다.
문서 전체에 할당하려면 document객체에 이벤트리스너를 추가해주면 된다.

다양한 이벤트 알아보기

마우스 버튼 이벤트

MouseEvent.button
0: 마우스 왼쪽
1: 마우스 휠
2: 마우스 오른쪽
MouseEvent.type
click → 클릭
contextmenu → 오른쪽
dblclick → 더블클릭
mousedown → 마우스 누르는거
mouseup → 마우스 떼는거
하나의 행동에서 여러 개의 이벤트가 뜬다
더블클릭하면 → 클릭이벤트가 두번 뜨고 더블클릭 이벤트가 발생한다.
운영체제 별로 마우스의 이벤트 순서가 다르다

마우스 이동 이벤트

MouseEvent.type
mousemove: 마우스 포인터가 이동할 때
mouseover: 마우스 포인터가 요소 밖에서 안으로 이동할 때
mouseout: 마우스 포인터가 요소 안에서 밖으로 이동할 때
MouseEvent.clientX, clientY →화면에 표시되는 창 기준 마우스 포인터
MouseEvent.pageX , pageY → 웹 문서 전체 기준 마우스 포인터
MouseEvent.offsetX, offsetY → 이벤트가 발생한 요소 기준 마우스 포인터 위치
그림으로 정리하면 좀 더 이해하기 쉬울테니 참고해 두시면 좋을 것 같아요! :)
mouseover, mouseout
mouseEvent.Target→ 이벤트가 발생한 요소
mouseEvent.relatedTarget → 이벤트가 발생하기 직전에 마우스가 위치해 있던 요소
위 코드에서는 mouseovermouseenter를 비교했지만, mouseoutmouseleave의 관계도 동일하다는 점 참고해주세요! :)
아무튼, 이 둘의 차이를 살펴봅시다.

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

mouseentermouseleave버블링이 일어나지 않습니다.
위 코드 결과에서 mouseover 타입으로 이벤트 핸들러가 등록된 div#box1요소(왼쪽)에서 마우스를 움직여 보세요.
당연히 해당 요소 바깥에서 안쪽으로 마우스 커서가 이동할 때도 이벤트가 발생하지만, 버블링과 이벤트 위임의 원리로 자식요소인 b.title 부분으로 마우스 커서가 이동할 때도 이벤트가 발생합니다.
하지만 mouseenter 타입으로 이벤트 핸들러가 등록된 div#box2요소(오른쪽)에서는 해당 요소 바깥에서 안쪽으로 마우스 커서가 이동할 때만 이벤트 핸들러가 동작하는 모습을 확인할 수 있습니다.

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

mouseentermouseleave자식 요소의 영역을 계산하지 않습니다.
다시 mouseover 타입으로 이벤트 핸들러가 등록된 div#box1요소(왼쪽)에서 마우스를 움직여 봅시다.
버블링에 의해 자식 요소로 마우스 커서가 이동할 때도 이벤트 핸들러가 동작하지만, 자식 요소에서 다시 div#box1요소로 마우스 커서가 이동할 때도 이벤트 핸들러가 동작하죠? mouseover는 자식 요소의 영역을 구분하기 때문입니다.
반면, mouseenter는 자식 요소의 영역을 구분하지 않기 때문에 mouseenter 타입으로 이벤트 핸들러가 등록된 div#box2요소(오른쪽)에서는 자식 요소에서 이벤트 핸들러가 동작하지 않는 것뿐만 아니라 자식 요소의 영역에 들어갔다 나올 때도 이벤트 핸들러가 동작하지 않는 모습을 볼 수 있습니다.

정리

mouseover/mouseout과 비교하면서 mouseenter/mouseleave에 대해 살펴봤는데요. 간단하게 정리하면, 이벤트가 자식 요소에 영향끼치는지가 둘의 가장 큰 차이라고 할 수 있습니다.
그래서 이벤트 핸들러가 자식 요소에까지 영향을 끼치게 하고싶은 경우에는 mouseover/mouseout을, 자식 요소에는 영향을 끼치지 않고 해당 요소에만 이벤트 핸들러를 다루고자 한다면 mouseenter/mouseleave를 활용하면 좋겠죠?

키보드 이벤트

keydown: 키보드 버튼을 누른 순간
→ 하나의 키를 계속 누를 때 계속 발생한다.
keypress: 키보드 버튼을 누른 순간
→ 출력값이 변하는 키 값에서만 동작한다.(esc, shift는 안 먹힘)
→하나의 키를 계속 누를 때는 한 번만 발생
→ 영어가 아닌 경우에는 반응하지 않는다.
keyup: 버튼을 눌렀다 뗀 순간
keyboardEvent.key : 이벤트가 발생한 버튼의 값
KeyboardEvent.code : 이벤트가 발생한 버튼의 키보드에서 물리적인 위치
대소문자 같은 경우에는 key값은 다른데 code값은 같다
shift 같은 경우에는 , key 값은 같은데 code값이 다르다

input 태그 다루기

text,password,button,checkbox
focus이벤트 → 키보드나 마우스 동작에 반응한다.
클릭하면 강조가 된다. 사용자의 동작에 반응할 준비가 되었다.
포커스가 되면 focusin, 다른 곳으로 포커스가 옮겨지면 focusout 이벤트가 발생
같은 이벤트를 가진 focus,blur → 버블링이 일어나지 않아서, 이벤트 위임이 되지 않는다.
focusin과 focusout이 많이 쓰이지만, blur랑 focus가 필요할 때도 있다.
입력과 관련된 이벤트→ input, change
input: 사용자가 입력을 할 때, 입력과 관련없는 키를 누르면 input이벤트가 안생긴다.
change: 요소의 값이 변했을 때, →입력이 시작되기 전 값과 완료되었을 때 차이가 있을 때만 발생한다. 입력이 진행중일 때는 지우고 해도 안생김.
focus가 빠져나갈 때 입력이 완료되었다고 받아들인다.
엔터키를 누르는것도 입력이 완료되었다고 받아들인다.

스크롤 이벤트

웹 문서의 크기가 브라우저의 창 크기보다 클 때, 스크롤이 자연스럽게 나타낸다.
스크롤 이벤트는 윈도우 객체에 등록되는 경우가 많다.
window.addEventListener('scroll',printEvent);
window.scrollY → 스크롤을 얼만큼 했느냐, y만큼
이걸 이용해서 스크롤을 얼만큼 하느냐에 따라서 디자인을 다르게 만들 수 있다.
스크롤의 방향을 감지하게끔 만들 수도 있다 → 스크롤의 이전 값을 저장함으로써ㅇㅇ