바닐라코딩

2주차 강의

단점이없어지고싶은개발자 2021. 7. 25. 13:05
반응형

DOM Review
2-1 DOM Introduction

DOM 이란 Documnet Object Model의 약자로 번역하면 HTML 문서를 위한 프로그래밍 인터페이스이다.

프로그래밍 인터페이스(Application Programming Interface a.k.a API)의 정의는 여러 소프트웨어 간의 교류를 가능하게 해주는 표면 같은 존재이다. 

예를 들면 티비를 시청하다가 다른 채널로 돌리려고한다면 리모콘에 다양한 버튼들을 이용해 TV와 교류할 수 있다. 이와 같은 상황에서 표면에 있는 버튼들이 프로그래밍 인터페이스와 같은 역할을 한다고 생각하면 된다. 

마찬가지로 DOM 이라는 인터페이스를 이용한다면, 여러분은 HTML 문서를 조종할 수 있다. 

const $text = document.querySelector(".some-text");
$text.textContent = "Hello, World";

위 코드에서 우리는 .some-text라는 클래스를 가진 요소를 선택하여 해당 요소의 텍스트를 수정할 수 있다. 
즉, 자바스크립트를 이용하여 HTML 문서를 조종할 수 있는 것이고, DOM이라는 프로그래밍 인터페이스가 있기에 가능한 것입니다. 

HTML 문서를 조종한다란 사실 정확히 말하자면, 우리는 자바스크립트를 이용해 HTML문서를 조종하는 것은 아니다.

HTML 문서란, 브라우저가 화면을 그리기 위한 초기 설계도의 역할을 할 뿐이다. 브라우저는 HTML이라는 설계도를 이용하여 초기 화면을 그리게 되고, 우리는 브라우저가 만든 이 화면을 DOM으로 접근하고 조종하게 되는 것이다. 

즉, 우리는 자바스크립트로 화면을 수정한다고해서 여러분이 작업한 HTML 문서 자체가 수정되는 것은 아니라는 의미이다.


2-2 Selecting Elements

요소 선택하기
요소를 선택하는 방법에는 4가지가 있다.


1. 아이디 이름을 선택하는 방법
2. 클래스 이름을 선택하는 방법
3. 태그 이름을 선택하는 방법
4. CSS선택자를 선택하는 방법

 <div class="container">
    <h1>I am first</h1>
    <p>I am Second</p>
  </div>
  <ul>
    <li class="it">
      <p>I am Second</p>
    </li>
    <li class="it">
      <p>I am Second</p>
    </li>
    <li class="it">
      <p>I am Second</p>
    </li>
    <li class="it">
      <p>I am Second</p>
    </li>
  </ul>
  <button id="button">I am a Button</button>

기본 HTML의 모습


1. 아이디 이름을 선택하는 방법

//button 아이디를 가진 요소를 선택하여 '$el' 변수에 대입
const $el = document.getElementById("button");

//button 아이디를 가진 요소의 텍스트를 변경할 수 있다
$el.textContent = "Button!!!!!!!";

버튼의 모습이 바뀌었다


document.getElementById를 이용하여 요소를 선택할 경우 우리에게 주어지는 값은 단 하나의 요소이다.

선택한 하나의 요소는 Node 혹은 HTML Element라고 부르는 존재이다. 
Node 가 포괄적인 상위 개념이고, HTML Element는 한 단계 하위 개념이다.

2. 클래스 이름을 선택하는 방법

//it 클래스를 가진 '모든 요소들'을 선택하여 '$it' 변수에 대입
const $it = document.getElementsByClassName("it");

//container 클래스를 가진 '모든 요소들'을 선택하여 $container'변수에 대입
const $container = document.getElementsByClassName("container");

//getElementsByClassName 의 결과값은 배열과 유사한 형태이므로 인덱스를 접근하여 사용한다.
$it[0].textContent = "it 1";
$it[1].textContent = "it 2";
$it[2].textContent = "it 3";

//HTML 상에서 해당 클래스를 가진 요소가 단 하나 뿐이더라도,
//getElementsByClassName의 결과값은 배열과 유사한 형태이므로 인덱스로 접근하여 사용 가능하다.
$container[0].style.backgroundColor = "green";

li 텍스트 변경 및 배경화면의 색을 넣어줬다


위 예제에서 getElementsByClassName 함수를 이용하여 변수에 할당한 존재는 모두 배열과 유사한 형태(유사배열)이다. 담긴 배열의 요소들이 하나의 HTML Element이다. 배열의 인덱스 위치를 이용하여 사용하여야 한다.

3. 태그 이름을 이용하여 선택하는 방법

// li 태그를 이용한 '모든 요소들'을 선택하여 '$list' 변수에 대입
const $list = document.getElementsByTagName("li");

// p태그를 이용한 '모든 요소들'을 선택하여 '$p" 변수에 대입
const $p = document.getElementsByTagName("p");

// getElementsByTagName의 결과값은 배열과 유사한 형태이므로 인덱스로 접근하여 사용한다
$list[0].textContent = "LIST 1";
$list[1].textContent = "LIST 2";
$list[2].textContent = "LIST 3";

//위치와 상관없이 모든 p 태그를 선택하게 되므로 $p 는 총 4개의 요소를 선택되고,
//그 중 인덱스의 요소에 따라 색깔을 바꿀 수 있다.
$p[1].style.backgroundColor = "red";


위 예제에서 getElementsByTagName 함수를 사용하여 선택한 결과값은 getElementsByClassName을 사용한 결과값과 동일한 형태(HTML Element가 담긴 유사 배열)입니다.

4. CSS선택자를 선택하는 방법
최근 가장 많이 선택하는 방법입니다. 괄호 안에 넣는 방법은 css선택하는 것 처럼 써주면 된다.

//querySelector라는 함수는 모든 경우에 '하나의 요소'를 반환한다. 가장 처음있는 요소를 반환
const $const = document.querySelector(".container");

const $button = document.querySelector(".button");

//주어진 요소가 여러개일 겨운 가장 첫번째 요소를 반환한다
const $it = document.querySelector(".it");

//qurerySelectorAll 함수는 주어진 CSS 선택자와 일치하는 '모든 요소들'을 우사배열의 형태로 반환한다.
//요소를 제거하고 싶다면 인덱스 위치를 사용해야한다
const $p = document.querySelectorAll("p");

2-3 Manipulating Elements
DOM을 이용하여 선택한 요소들을 필요에 따라 수정하거나 삭제할 수 있다.

const $heading = document.querySelector("h1");
$heading.textContent = "I am h1 yeah~~~~";


위의 예제와 같이 textContent 란 속성을 이용하여 h1요소의 텍스트 내용을 수정할 수 있다.

HTML의 요소 대상으로 어떻게 해야될지 모르겠다면 '자바스크립트 HTML 요소 텍스트 수정' 등의 키워드로 검색하면 찾을 수 있다. 

Element.classList 그 자체는 읽기 전용 프로퍼티지만 add() 와 remove() 메서드를 이용해 변형 할 수 있다.

add(string) : 지정한 클래스 값을 추가한다. 만약 추가하려는 클래스가 존재한다면 무시한다.

remove(string) : 지정한 클래스 값을 제거한다.

toggle(string) : 하나의 인수만 있을 때, 클래스 값을 토글링한다. 즉, 클래스가 존대한다면 제거하고, false를 반환하며, 존재하지 않으면 클래스를 추가하고 true를 반환한다.

contains(string) : 지정한 클래스 값이 엘리먼트의 class 속성에 존재하는지 확인한다.

replace(oldClass, newClass)존재하는 클래스를 새로운 클래스로 교체한다.

 

Element.innerHTML 요소 내에 포함된 HTML을 가져오거나 설정한다

 

Element.style : element.style.backgroundColor = "red" 이런식으로 style을 이용해 HTML의 CSS를 줄 수 있다.

 

Node.appendChild() 메소드는 한 노드를 특정 부오 노드의 자식노드 리스트 중 마지막 자식으로 붙인다. 만약 주어진 노드가 이미 문서에 존대하는 노드를 참조하고 있다면 appendChild() 메소드는 노드를 현재 위치에서 새로운 위치로 이동시킨다. 

 

Element.children : 현재 요소의 자식 요소가 포함된 HTML Collection을 반환한다. 비 요소 노드는 모두 제외된다. 노드가 필요 없다면 children 프로퍼티를 사용하면 된다. 

 

이 외에도 많은 메소드들이 있는데 https://developer.mozilla.org/en-US/docs/Web/API/Element 참조하면 좋을 것 같다.


2-4 Creating Elements

수정과 삭제가 가능하다면 생성도 가능하지 않을까?

//h2 요소 만들어서 'h2' 변수에 할당
const h2 = document.createElement("h2");

//방금 생성한 'h2' 요소의 텍스트 설정
h2.textContent = "두번째";

//h2 요소의 스타일 설정
h2.style.fontSize = "50px";

//방금 생성한 h2 요소를 body 태그의 자식으로 추가
document.body.appendChild(h2);

위 예저처럼 우리가 원하는 요소를 만들고, 글씨를 수정하고 스타일을 수정할 수 있다. 우리가 원하는 자리에 추가 또한 할 수 있다.

우리가 자바스크립트로 생성한 요소는 우리가 직접 화면 어딘가에 명시적으로 추가하기 전까지는 시각적으로 화면에 나타나지 않는다. 

예제코드에서 document.body.appendChild(h2); 라는 코드가 없었다면 나타나지 않았을 것이다.


2.5 Events

이벤트란 웹 상에서 발생하는 사건들을 통칭하는 단어입니다. 예를 들면, 사용자가 화면의 일부를 '클릭'하거나 마우스를 이용해 드래그하거나 윈도우의 사이즈를 줄이거나 하는 행위이다. 

 

이벤트를 감지하는 방법

우리는 자바스크립트를 이용하여 DOM요소를 기준으로 이벤트를 감지하고 우리가 원하는 작업을 수행할 수 있다.

이벤트를 발생시킬 때 addEventListener 라는 메소드를 이용한다.  addEventListener('이벤트메소드', 실행 내용을 담을 함수)


3-1 Scope Introduction


Scope란, 우리가 작성하는 코드의 접근 범위를 결정하는 개념이다.

function foo() {
//foo scope start

var x = 1;

console.log(x); // 1

//foo scope end
}

foo();

 

var을 이용하여 선언한 변수는 함수를 기준으로 접근 범위가 결정된다.

 

Variable Scope Details

  foo라는 함수를 만들었다. 함수 내부에서 변수 x를 선언했다. 현재 x라는 변수를 사용하려고 시도한 곳은 '1' 부분이다.

 

'1'에서는 x라는 변수의 값 (1)이 성공적으로 출력된다. 자바스크립트에서 var을 이용하여 선언한 변수는 해당 변수 선언문을 감싸고 있는 함수를 기준으로 접근 범위가 설정되고 그 범위 내부에서는 자유롭게 접근하여 사용할 수 있다. 

'foo scope start' 부분부터 'foo scope end' 부분 내에서는 언제든지 자유롭게 x라는 변수에 접근하여 사용 가능하다.

이 부분을 foo 함수 scope라고 부른다.


3-2 Scope Chain

var x = 1;

function foo() {
var x = 2;
consol.log(x);
}

foo();

위 예제는 2가 찍힌다. 이유는 어떤 변수에 대한 정보를 필요로 할 때, 자바스크립트는 현 실행문의 위치를 기준으로 하위 Scope부터 시작하여 해당 변수의 값을 찾아나간다.

 

var x = 1;

function foo() {
var x = 2;
consol.log(x); //2
}

foo();
console.log(x); //1

  상위 Scope에서 하위 Scope내부 정보를 탐색할 수 없다. 즉, 변수를 선언 할 때, 해당 변수가 사용되는 스코프를 잘 판단하여 불필요하게 상위 스코프에 선언하지 않도록 한다. 만약 var x =1; 이 없었다면 아래 콘솔로그는 에러가 나올 것이다. 

 

  현재 Scope에서 원하는 정보를 찾지 못하고 상위 Scope가 존재한다면, 상위 Scope를 탐색한다. 이런 방식으로 Global Scope까지 탐색을 계속하며, 원하는 정보를 찾으면 탐색을 멈춘다.


3-3 Global Scope

 

Global Scope란 공용공간이라고 보면 좋다.

하나의 웹페이지에는 하나의 Global Scope가 존재하고, 여러 개의 script가 사용할 수 있는 공용공간이다. 다른 사람이 수정/삭제할 가능성도 있다. 필요하다면 사용해야하지만, 주의를 기울여 신중하게 사용해야 한다.


3-4 Hoisting

Hoist란, 들어올리다, 승강장치, 어떤 사물을 끌어올리는 장비를 일반적으로 Hoist라고 한다.

자바스크립트에서 우리가 사용하는 모든 변수 선언문은 스코프 내에서 최상위로 Hoisting 된다.

console.log(x);
var x = 1;

위의 예제를 실행했을 때 나타나는 출력결과는 undefined이고, 이것이 바로 Hoisting이라는 현상 때문이다.

작성한 실제 코드는 위와 같더라도, 해당 코드가 실행되는 '코드 구동 흐름'은 아래와 같다고 생각하면 된다.

var x;
console.log(x);
x = 1;

코드의 최상위로 이동한 부분이 바로 '변수 선언' 부분이다.

작성하는 모든 변수 선언문은 해당 코드가 속한 스코프 내에서 최상위로 끌어올려진 상태로 실행된다. 코드가 실행되기 전에 진행되는 전처리 작업 중 하나라고 생각해도 좋다. '변수 선언문'만 올려진다는 점이다. 변수에 값을 대입 혹은 할당하는 구문은 우리가 실제로 작성한 흐름과 같이 실행된다.

 

Function Expression (함수표현식)

모든 변수 선언문에 대해 해당하는 흐름이기 때문에, 함수를 대입하는 경우에도 동일하게 적용된다. 그래서 함수 표현식으로 함수를 작성하는 경우에는 항상 실행문의 위치와 함수를 대입하는 구문의 위치가 중요한다.

 

x(); // 에러 발생 

var x = function() {
	console.log('Hello');
  };
x();

 

Function Declaration (함수 선언식)

함수 선언식으로 작성된 함수의 경우에는 항상 최상위로 Hoisting되어 실행문의 순서가 중요하지 않아 편리하다

x(); //x

function x() {
console.log('x');
}

x(); //x
//둘 다 나온다
반응형

'바닐라코딩' 카테고리의 다른 글

3주차 과제 카드퀴즈만들기  (0) 2021.08.11
3주차 강의 ES2015 & beyond  (0) 2021.08.07
2주차 과제 틱택토(tick-tack-toe)  (0) 2021.07.31
1주 - 첫 과제  (0) 2021.07.23
1주차 JavaScript Review  (0) 2021.07.20