
노마드코더의 <바닐라 JS로 크롬 앱 만들기>를 수강하며 배우거나 추가적으로 찾아본 것들을 정리한 내용입니다.
개념 복습용이나 면접 대비용으로 참고하면 좋을 듯 합니다!
문법 말고 브라우저에 초점 맞춰서 js 배우는 챕터였다
document라는 걸 콘솔에 입력해줬는데 object (HTML) type이 출력됐다
→ 즉 도큐먼트는 html 문서를 나타내는 객체
console에 document.title을 출력해보자 (title은 html 파일에서 이미 정의한 항목)
→ JS에서 title을 정의한 적이 없음에도 불구하고, document가 HTML을 보여줌!
근데 JS의 관점인…
.
.
.
..말이 좀 어려워서 다시 정리해봤는데 …
HTML은 CSS와 JS를 적용해주는 접착제의 역할임
HTML은 구조나 틀을 정의하지만
CSS는 디자인을 적용하고
JS는 HTML과 상호작용해서 ‘인터렉티브한 언어’라고도 하는데 이를 통해 동적인 기능을 추가할 수 있는 것
→ 즉 js를 통해 HTML의 Element를 건드릴수 있게된다.
정확히는 document (type: object)는 HTML을 표현함, 근데 JS의 시선으로 바라보는 것이다(JS의 문법이니까)
== 브라우저 환경에서 JavaScript를 사용할 때 매우 중요한 객체임
(+추가_ document 객체는 JS 문법이라기 보단, 브라우저가 제공하는 DOM(Document Object Model) API의 일부임, 브라우저 환경에서 실행될때 document를 통해 HTML을 조작할 수도 있음)
즉, 브라우저가 HTML 정보가 들어있는 document라는 object를 전달함
== HTML 코드를 JS의 관점에서 보고(접근하고) 있음
JS에서 document 객체를 사용하면 HTML 요소를 가져오기/조작 가능함
ㄴ> 가져오는 법: console.log(document.title); // 현재 웹 페이지의 제목 출력
ㄴ> 조작하는 법: document.title = “~”;
document.getElementById(”something”) 라는 걸 배움
HTML의 항복을 가져오는 함수인데, Id로 Element를 가져올 수 있게 해줌
즉 Id가 something인 요소를 찾는 코드
something에는 type: string만 들어갈 수 있음!
const titleVar = document.getElementById(”title”);
(주의: id=”title”인 요소가 실제 HTML에 존재해야함)
ㄴ ex:
<h1 id="title">Hello</h1> // index.html
이렇게 있어야 titleVar이 h1 요소를 참조할 수 있음!
const titleVar = document.getElementById(”title”); // app.js
title.id= “Got You!”; → 이로써 js에서 HTML의 코드를 변경하게 됨
console.log(title.className); → HTML 코드 가져오기
element를 가지고 오는 모든 방법에 대하여 … - Array편
getElementBy~ = “something”
역시 여기서 something은 HTML의 Id 혹은 className과 일치해야함
const title = document.getElementByTagName(”h1”);
역시 이 코드로 TagName이라는 요소를 가지고 올 수 있음
BUT! 특정 h1 태그만을 가져올 수는 없음, 모든 h1 태그를 불러오게 됨
So, Element를 가지고 오는 "멋진" 방법에 대하여…! - querySelector편
→ Element를 CSS 방식(CSS Selector)으로 검색할 수 있음
: 즉 단 하나의 요소만 불러오기가 가능해진다는 것! (not Array) → 앞으로 이 방법만 사용될 예정
class를 찾고 그 안의 h1을 불러오는 방식
: document.querySelector(” .클래스이름 h1 ”)→ 불러올 특정 태그를 CSS selector(클래스, id, 태그 등등…)로 전달
꼭 이해해야할 것
HTML은 접착제. 반드시 있어야하는 것! →
HTML에서 app.js를<script src="app.js"></script>
해줬기 때문에 JS를 통해 HTML의 내용(Element)를 가져올 수 있는 것
→ 이 때문에 document라는 object도 사용이 가능한 것
→ browser가 document에 액세스 할 수 있게 함!
const title = document.querySelector(”.클래스이름 태그이름”);
태그이름.style.color = “blue”;
BUT, 앞으로는 event 발생보단 대부분 event를 LISTEN 하는 법을 배울 것
[event의 실행 Process]
1. element를 찾는다.
2. event를 listen한다.
3. 그 event에 (함수로) 반응한다.
- Event Listener 사용법
htmlElement이름.addEventListener(”이벤트이름”, 함수이름);
- Click(Event)을 Listen 하는 법
title.addEventListener(”click”, 함수)
이 때 event 뒤에 쉼표로 구분 된 ‘함수’는 addEventListener의 2번째 argument인데 함수에 괄호를 넣지 않아도 됨
🙋♀️ Q: 왜 안넣어도 돼용?
📢 A: 위의 코드에서 함수를 인자로 넘겨줄 때, "함수()"와 같이 작성하게 된다면 함수를 실행시켜 버리게 된다...
우리의 의도는 querySelector가 지정하는? 요소가 클릭되었을 때
자바스크립트가 해당 이벤트를 감지한 후, 대신 함수를 실행할 수 있도록 하는 것이므로,
바로 실행되지 않고 인자로만 넘어갈 수 있도록 ()를 없애고 함수명만 넘겨줘야 한다.
위 addEventListener는 클릭을 했을 때 이벤트를 발생시킬 함수(이벤트에 대한 반응)이름를 적어준 것이다
== "`title`에 `click`이 발생힐 경우, `함수`로 반응한다!"
Event 종류 알기
방법 1. mozila Developer Network(MDN)에 검색 → 찾아보면 JS의 Element를 알 수 있음
방법 2. console.dir(~) → ~에는 element명 넣으면 된다 (ex: title, header 등)
이 때 콘솔에 property들 출력될 텐데, on~으로 시작하는 건 전부 사용 가능한 event listener
ex: onclick, onabort (n가지의 event를 listen 할 수 있음!)
예제
const btn = document.querySelector("button");
console.dir(btn); // 버튼 요소의 속성과 메서드를 확인 가능
위 코드 실행 시 버튼의 onclick, disabled, innerText, classList 등의 속성과 매서드(객체가 가지고 있는 동작)를 알 수 있음
1. htmlElement이름.addEventListener(”click”, 함수이름);
2. htmlElement이름.onClick = 함수이름;
→ 강의에서는 htmlElement이름.removeEventListener가 가능해서 방법1을 더 선호한다고 함
window.addEventListener(”resize”, handleWindowResize);
function handleWindowResize() {
document.body.style.backgroundColor="tomato";
cf) 왜 document 하위 항목에 body가 있나?
→ HTML에서 정의된 body의 backgroundColor를 바꿔주는 거니까!
document는 HTML 문서 전체를 의미하기 때문에 스타일 속성이 없음. 즉 document.style.backgroundColor는 존재하지 않음
🙋♀️ Q: 그럼 이때 document.title.style.backgroundColor처럼 body는 title element를 가져오는 것은 안되나요?
→ 안 됩니다! document.title은 tag가 아니라 “string”이므로 .style을 사용할 수 없음
즉 document.title은 DOM요소(title요소의 내용)가 아니라 그를 나타내는 단순한 string이므로 스타일 속성을 가질 수 없음
+) 마찬가지로 document의 하위항목으로 가져올 수 없고 HTML 요소는 접근 가능! (ex: head, body, title)
즉 console에서 HTML body 태그에 document를 통해 접근 가능함
-> document.body
BUT, document.div와 같은 비주류? 태그는 불가능하고, head, body, title 등과 같은 주요 태그만 document.~ 가능!
정리!
Event를 사용하는 2가지 방법
addEventListener - 선호됨**
1. h1.addEventListener(”click”, handleTitleColor);
2. h1.removeEventListener
onClick, onAbort … 등
1. title.onClick = handleTitleColor;
EventListenter 실습!
: title 클릭할 때마다 blue ↔ tomato 로 color change
if - else문 사용
if (h1.style.color === "blue") {
h1.style.color = "tomato";
}
else {
h1.style.color = "blue"}
그러나.. 개선해야할 점: 언제나 중복을 줄이기!
const currentColor = h1.style.color;
if (currentColor === "blue") {
currentColor = "tomato";
}
else {
currentColor = "blue"}
}
개선해야할 점: newColor라는 새로운 변수 추가 설정
예상도: title.addEventListener("click", handleTitleColor);
function handleTitleColor() {
const currentColor = h1.style.color;
let newColor;
if (currentColor === "blue") {
newColor = "tomato";
}
else {
newColor = "blue"}
h1.style.color = newColor;
}
주의 할 점:
코드 마지막 줄에 currentColor = newColor;로 작성하면 안됨. currentColor는 컴퓨터입장에선 단순 변수이므로 실질적으로 h1.style.color를 바꿔주는 게 아님!
기존 문제 상황: 이전에는 js 파일에서 h1.style.color = “blue”; 이런 식으로 바꿔줌
그러나
JS = 동적인 언어
CSS = 스타일 지정 이라는 명확한 역할이 있음
그래서 .. 앞으로 목표:
CSS 파일과 소통하는 법 배우기!
앞으로 모든 스타일적 요소는 css 파일에서만 바꿔주는 실습을 해볼 것
// style.css
h1 {
color: blue;
}
.active {
color: tomato;
}
// app.js
function handleTitleColor() {
h1.className = "active";
}
이제 클릭 시, blue ↔ tomato 되도록 바꿔보기
const h1 = document.querySelector('.hello');
function handleTitleColor() {
h1.className = "active";
if (h1.className === "active") {
h1.className = " "; // empty 라는 뜻
}
else {
h1.className === "active"; }
}
코드 설명:
//style.css 파일에서 h1의 기본 색은 blue (empty)로 지정했으므로 event 발생 시 클래스 이름이 active (tomato)로 바뀌면 blue ↔ tomato가 됨
BUT, 코드는 언제나 깔끔하게!
문제상황: 위 코드에서는 h1.className = “active”가 중복되고 있음
만약 “active”라는 raw value를 수정하게 되면 비효율적으로 코드를 수정해야함
해결: 오류의 위험과 재사용성이 낮은 raw string (사용자 임의 지정)을 중복 사용하는 것보다는, raw string을 담은 변수를 선언하고 그 변수를 사용해주자!
기억하자. 변수에 담는 건 매우 유용하다는 것을 🤩🤩
const h1 = document.querySelector('.hello');
function handleTitleColor() {
const clickedClass = 'active';
if (h1.className === clickedClass) {
h1.className = " "; // empty 라는 뜻
}
else {
h1.className === clickedClass; }
}
h1.addEventListener("click", handleTitleColor);
또 다시 생긴 현재 문제점:
HTML에서 ClassName 정의 후, JS에서 eventlisten후 함수를 실행시키면서 이미 선언 된 ClassName을 다른 이름으로 바꿔버린다면?
→ HTML의 className과 그를 뒤따라오는 속성들은 사라지게 됨 (ex: 폰트, 색상 등)
즉 className 은 이전 class는 신경쓰지 않고 모든 걸 교체해버린다
다시 말해, 이미 className이 존재하는 상태라면? JS에서 className 그 자체를 바꿔버리는 것은 좋은 방법이 아니다
해결방법:
classList를 사용하면 된다! 기존 클래스를 유지하면서 새로운 클래스를 추가/삭제하는 것이 가능하다.
<!-- index.html -->
<body>
<div class="hello">
<h1 class="font">Hello World!</h1>
</div>
// app.js
const h1 = document.querySelector('.hello');
function handleTitleColor() {
const clickedClass = 'active';
if (h1.classList.contains(clickedClass)) {
h1.classList.remove(clickedClass); // empty 라는 뜻
}
else {
h1.classList.add(clickedClass); }
}
h1.addEventListener("click", handleTitleColor);
즉 className 그 자체를 바꾸지 않고 ClassList의 contains, remove, add 등 function을 통해 특정한 className만 추가/제거 등 변경하도록 한다
classList는 class들의 목록으로 작업 할 수 있게 해줌
+) 위의 작업을 더 편하기 위해 사용하는 것이 Toggle!!
const h1 = document.querySelector('.hello h1');
function handleTitleColor() {
h1.classList.toggle('active');
}
h1.addEventListener("click", handleTitleColor);
변수 h1의 classList에 active 클래스가 이미 있는지를 toggle이 확인해주고,
만약 있다면 → active 클래스를 remove
만약 존재하지 않는다면 → active 클래스를 add
즉 변수.classList.toggle(’클래스이름’); 으로 사용!
토글을 잘 사용하는 것이 깔끔한 코드에 있어서 매우매우 중요함을 느꼈다 🤔
드디어 3강 끝! 그동안 머릿속에서 애매하게 정리 됐던 개념을 다시 파고 들어서 하나하나 완벽히 이해하느라 좀 시간이 걸렸다. 다음 강부터는 진짜 Momentum 사이트 Build 시작!
요즘 주변에 노마드코더 강의를 많이 추천하는 중이다
그 전엔 개념들을 이해하지 못한 채 마감기한에 쫒겨 할 일을 마냥 쳐내기만 했는데
요즘엔 "이거는 이렇기 때문에 이렇다!" 라고 깔끔하게 정리되는 느낌이다!
그리고 무엇보다 무료여서 참 좋다...
앞으로 본격적인 클론 코딩을 하며 배울 내용들이 기대된다 ㅎㅎㅎ