노마드 코더 바닐라 JS로 크롬 앱 만들기 #3

ᴄsᴇ ᴘᴇʙʙʟᴇ·2022년 8월 5일
0
post-thumbnail

노마드 코더의 바닐라 JS로 크롬 앱 만들기 강의를 듣고 내용을 정리합니다.


🦖 HTML과 Javascript

Javascript를 사용하는 이유는 HTML과 상호작용하기 위해서이다.
JS를 통해 HTML의 element들을 변경하고, 읽을 수 있다.

JavascriptHTML에 이미 연결되어 있기 때문에 별다른 연결을 해줄 필요가 없다.

🦖 브라우저의 핵심 object인 document

document는 브라우저에 이미 존재하는 object로 HTML을 가리킨다. HTML 파일을 보여준다. 이 document가 JavascriptHTML 파일을 가져오도록 해주는 시작점이다.

console창에 document.title이라고 치면 HTML의 title에 접근하여 해당 title의 content를 보여준다.

title은 document의 properties(속성)으로, 속성은 변경이 가능하기 때문에 HTML 파일을 직접 수정하지 않아도 console 창에서 수정할 수 있다. 즉 JSHTML 요소에 접근하여 수정이 가능하다는 것이다.
document.title = "수정할 제목"
과 같이 작성해주면 된다.


그렇다면 어떻게 JavascriptHTML의 특정한 element를 가져오고 접근할 수 있을까?

🦖 getElementByID()

원하는 요소의 ID로 접근하여 해당 요소를 가져온다.

document.getElementByID("타켓 태그의 id");

🦖 element를 찾은 후 HTML 바꾸기

getElementByID와 같이 element를 찾은 후, HTMLJS에서 원하는대로 접근하거나 바꿀 수 있다.

// HTML에서 h1 태그를 찾고자 하고, 해당 태그의 id가 abc라고 가정하자.
const element = document.getElementById("abc");

element.innerText = "Got you!"; // innerText는 h1의 contents를 의미

console.log(element.id); // console창에 abc가 출력된다.
console.log(element.className); // h1 태그에 class 부여는 안했으므로 console 창에는 아무것도 출력되지 않는다.

🦖 HTML의 요소(태그)를 가져오는 다양한 방법

getElementByID()

위에서 설명했듯 getElementById는 id로 접근하여 가져오는 것

getElementsByClassName()

class name으로 접근하여 가져오는 것. 하지만 해당 class name을 가진 모든 태그들을 가져와서 하나의 배열에 저장하기 때문에 많은 element를 한번에 가지고 와야하는 경우에 사용한다.

const hellos = document.getElementByClassName("hello");
// class name이 hello인 모든 element들을 가져온다.

getElementsByTagName()

태그명으로 접근하여 가져오는 것. ByClassName과 마찬가지로 해당 태그명을 가진 모든 tag들을 한꺼번에 array로 가져온다.

const title = document.getElementsByTagName("태그명");

querySelector()

querySelector는 element를 CSS 방식으로 검색할 수 있다. CSS selector를 사용하여 검색할 수 있다는 것이다. 예를 들면 동일한 class명을 지니고 있는 여러 요소(태그)들 중에 특정 태그명을 가진 태그만 가져올 수 있다.

가장 많이 사용한다. querySelector는 ByClassName이나 ByTagName과 달리 단 하나의 element를 return 해주기 때문이다. 만약에 조건에 맞는 해당 태그가 여러개라면 첫 번째 것만 가져온다.

const title = document.querySelector(".hello h1"); // hello 클래스의 h1 태그를 가져온다

const title = document.querySelector("#hello"); // id가 hello인 태그를 가져온다.
// const title = document.getElementsById("hello"); 와 동일하다.

const title = document.querySelector("#hello h1"); // id가 hello인 h1 태그를 가져온다.
// getElementsByID에서는 이와 같이 해줄 수 없다.

const title = document.querySelector("div.hello:first-child h1");
// div 태그 중 class명이 hello이고 first-child인 h1 태그를 가져온다.

만약 다 가지고오고 싶다면 querySelectorAll()을 사용하면 된다. 이것은 ByClassName과 ByTagName과 동일하게 한꺼번에 array로 가져온다.

🦖 querySelector로 HTML style 바꾸기

const title = document.querySelector("div.hello:first-child h1");
title.style.color = "blue"; // color라는 property(속성)을 변경해준 것

🦖 Event

click을 하거나, 마우스를 올리거나, 입력을 끝내거나, enter를 누르는 등이 event이다.

Javascript는 이 모든 event들을 listen 할 수 있다.

const title = document.querySelector("div.hello:first-child h1");
title.addEventListener(이벤트명); 

eventListener는 말 그대로 event를 listen 하는 것이다.

click event

element를 클릭하면 event가 발생한다.

const title = document.querySelector("div.hello:first-child h1");

function handleTitleClick() { // 이벤트 발생시 특정 일을 해주는 함수
  console.log("title was clicked!");
}
title.addEventListener("click", handleTitleClick); 
// 이벤트 발생시 실행할 함수를 두 번째 인수로 전달

다른 예시

const title = document.querySelector("div.hello:first-child h1");

function handleTitleClick() { // 이벤트 발생시 특정 일을 해주는 함수
  title.style.color = "blue";
}
title.addEventListener("click", handleTitleClick);

mouseenter

마우스가 element 위에 올라가면 이벤트가 발생한다.

const title = document.querySelector("div.hello:first-child h1");

function handleMouseEnter() {
  console.log("The mouse is here!");
}
title.addEventListener("mouseenter", handleMouseEnter);

mouseleave

마우스가 element 위에 올라갔다 떠나면 이벤트가 발생한다.

const title = document.querySelector("div.hello:first-child h1");

function handleMouseEnter() {
  title.innerText = "Mouse is here!"// innerText는 h1 태그의 contents를 의미
}

function handleMouseLeave() {
  title.innerText = "Mouse is gone!";
}
title.addEventListener("mouseenter", handleMouseEnter);
title.addEventListener("mouseleave", handleMouseLeave);

resize

window에서 사용할 경우, window 창의 크기를 조정하면 발생하는 event

function handleWindowResize() {
  document.body.style.backgroundColor = "tomato";
}

window.addEventListener("resize", handleWindowResize); // window는 전체 창을 의미함. 

그런데 document의 body, head, title 이런 것들은 중요하기 때문에 기본적으로 존재하지만, 나머지 element들은 querySelector나 getElementById 등으로 찾아와야 한다.

copy

사용자가 복사를 할 경우 발생하는 이벤트

function handleWindowCopy() {
  alert("Copier!");
}

window.addEventListener("copy", handleWindowCopy); // window는 전체 창을 의미함. 

online/offline

와이파이 연결이 되었을 경우/끊길 경우 발생하는 event

function handleWindowOffline() {
  alert("SOS no WIFI");
}

function handleWindowOnline() {
  alert("ALL GOOD");
}
window.addEventListener("offline", handleWindowOffline);
window.addEventListener("online", handleWindowOnline);

🦖 event를 listen하는 또다른 방법

const title = document.querySelector("div.hello:first-child h1");

function handleTitleClick() { 
  console.log("title was clicked!");
}

function handleMouseEnter() {
  title.innerText = "Mouse is here!"// innerText는 h1 태그의 contents를 의미
}

function handleMouseLeave() {
  title.innerText = "Mouse is gone!";
}

title.addEventListener("click", handleTitleClick); 
title.addEventListener("mouseenter", handleMouseEnter);
title.addEventListener("mouseleave", handleMouseLeave);

이 코드는 위에서 해왔던 방법인데, 또다른 방법이 있다.

const title = document.querySelector("div.hello:first-child h1");

function handleTitleClick() { 
  console.log("title was clicked!");
}

function handleMouseEnter() {
  title.innerText = "Mouse is here!"// innerText는 h1 태그의 contents를 의미
}

function handleMouseLeave() {
  title.innerText = "Mouse is gone!";
}

title.onclick = handleTitleClick;
title.onmouseenter = handleMouseEnter;
title.onmouseleave = handleMouseLeave;

하지만 addEventListener를 사용하는 것이 더 좋다. 왜냐하면 나중에 .removeEventListener를 통해 event listener를 제거할 수 있기 때문이다.

🦖 listen하고 싶은 event 찾기 팁

1. 구글링

구글에 찾고 싶은element이름 html element mdn 검색하기!
ex) h1 html element mdn

mdn 문서 중에 Web APIs 라는 문장이 포함된 페이지를 들어간다.
Javascript 관점의 HTML Heading Element를 여기에서 확인할 수 있다.

2. 콘솔창에 element 출력

const title = document.querySelector("div.hello:first-child h1");
console.dir(title);

console.dir은 element의 properties들을 출력해준다. properties들 중 이름 앞에 on이 붙어있다면 그것이 바로 event listener이다. 실제 코드 작성 시에는 on을 빼고 작성하면 된다.


🦖 예시 - 클릭할 때마다 blue->tomato로 색 변환되는 event

const a = document.querySelector("h1");

function handleClick() {
  const currentColor = a.style.color;
  let newColor;
  if (currentColor == "blue") {
    newColor = "tomato";
  } else {
    newColor = "blue";
  }
  a.style.color = newColor;
}
a.addEventListener("click", handleClick);

🦖 getter와 setter

h1.style.color와 같이 h1의 color을 얻을 수 있는 것 등은 getter이고,
h1.style.color = "blue"; 와 같이 color를 변경해주는 것 등은 setter이다.


🦖 총정리

  1. element를 찾아라
  2. event를 listen해라
  3. 그 event에 반응하라 (무언가를 보여주거나, 감추거나, 색을 바꾸는 등)

🦖 Javascript에서 변경하는 style

위에서는 JS로 style을 변경했지만 사실은 CSS가 하는 것이 좋다.
style 작업에 적합한 도구는 CSS이고, animation에 적합한 도구는 Javascript이다.

🦖 HTML 파일에 CSS import 하기

head 안에서 title 태그를 작성하기 전에 아래와 같은 코드를 작성해주면 된다.

<link rel="stylesheet" href="CSS파일명.css" />

🦖 위에서 했던 예시에서 style을 CSS에서 해주자

CSS

body {
  background-color: beige;
}

h1 {
  color: cornflowerblue;
}

.active { // active는 내가 작성한 클래스명임
  color: tomato;
}

JS

const h1 = document.querySelector("h1");

function handleClick() {
  const activeClass = "active";
  if (h1.className === activeClass) {
    h1.className = "";
  } else {
    h1.className = activeClass;
  }
}
h1.addEventListener("click", handleClick);

하지만 이 코드의 문제점은 만약 기존에 다른 class명을 가지고 있었고 그 class명에 해당하는 CSS가 적용이 되어있었다면 className을 바꿈과 동시에 해당 CSS는 의미가 없어져버린다.

아래와 같은 경우이다.

html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="style.css" />
    <title>Document</title>
  </head>
  <body>
    <h1 class="sexy-font">Hello!</h1> // h1에 기존의 class가 있음
    <script src="app.js"></script> 
  </body>
</html>

CSS

body {
  background-color: beige;
}

h1 {
  color: cornflowerblue;
}

.active {
  color: tomato;
}

.sexy-font { // 이 부분 확인
  font-family: "Courier New", Courier, monospace;
}

그렇기 때문에 className보다는 classList를 사용하는 것이 좋다.

classList는 우리가 class들의 목록으로 작업할 수 있도록 허용해준다.
아래와 같이 사용하면 된다.

const h1 = document.querySelector("h1");

function handleClick() {
  const activeClass = "active";
  if (h1.classList.contains(activeClass)) { //classList가 active class를 포함하고 있는지 확인
    h1.classList.remove(activeClass);
  } else {
    h1.classList.add(activeClass);
  }
}
h1.addEventListener("click", handleClick);

그런데 이 코드를 더욱 간단하게 할 수 있다.
위와 같은 일은 자주 발생하는 일이기 때문에 이것을 해결해줄 function이 개발되어 있다.
바로 toogle이다.

toogle 함수는 class name이 존재하는지 확인을 해준다. 만약 class name이 존재할 경우 해당 class name을 제거하고, 존재하지 않는다면 class name을 추가한다.

toogle 함수를 적용한 코드는 아래와 같다.

const h1 = document.querySelector("h1");

function handleClick() {
  h1.classList.toggle("active");
}
h1.addEventListener("click", handleClick);

toogle은 껐다 켰다 해주는 스위치같은 것이라고 생각하면 된다.

profile
ꜱɪɴᴄᴇ 2021.09.01

0개의 댓글