JavaScript

HTML 문서와 웹 브라우저를 동적으로 조작하는 JavaScript를 이해하고, 그 문법에 대해서 알아봅니다. 브라우저 객체 모델과 문서 객체 모델을 학습합니다.
JavaScript, 브라우저 객체 모델, 문서 객체 모델, DOM, BOM


JavaScript 기초

웹 프론트엔드 3형제웹 프론트엔드 3형제

HTML, CSS와 더불어 JavaScript는 웹 프론트엔드를 구성하는 중요한 역할을 하고 있습니다. Node.js 환경에서 JavaScript 문법을 익혔는데,
Node.js의 시초가되는 JavaScript는 브라우저 위에서 동작하는 스크립트 언어입니다. 웹 페이지에서 HTML 요소(Element) 등을 동적으로 제어하기 위해서 진짜(?) JavaScript에 대해서 공부해보도록 하겠습니다.

HTML은 구조를, CSS는 외관을, JavaScript는 동작을 제어HTML은 구조를, CSS는 외관을, JavaScript는 동작을 제어

HTML에 JavaScript를 적용하는 방법에는 두가지가 있습니다.

script 태그에 인라인으로 작성

script 태그로 외부 파일을 참조

<!doctype html>
<html>
<head>
    <link rel="stylesheet" type="text/css" href="./some/path/style.css">
    <script src="/some/js_file.js"></script> <!-- script 태그는 꼭 닫아줘야 합니다. -->
</head>
<body>
<script src="/some/js_file2.js"></script>
</body>
</html>

브라우저 객체 모델

브라우저 객체 모델(BOM; Browser Object Model)웹 브라우저의 창(탭)에 관련된 기능들을 JavaScript로 제어할 수 있도록 추상화한 객체의 집합입니다. JavaScript에서 접근 할 수 있는 모든 전역 객체와 값들은 window라는 최상위 브라우저 객체 (머리 객체)에 연결되어 있습니다.

개발에 있어서는 단순히 수 많은 API를 공부하면서 메소드와 속성들에 대해 암기하는 것이 능사가 아닙니다. 큰 그림을 이해하고 분명히 이런 기능이 있을 것이다라고 확신 할 수 있는 배경 지식이 필요합니다. 기능에 대해서 생각해보고 추측해보면서, 또 인터넷에 검색해보면서, 조금씩 능숙해지면 됩니다. 모든 것을 공부 할 수는 없습니다. 배경 지식을 키웁시다.

// 모든 전역 객체나 값은 머리 객체 window에 연결됩니다.
var x = 10; // window.x == 10
var y = "abc"; // window.y == "abc"


/** window 객체 **/
window.open('http://google.com'); // 창 열기
window.close(); // 창 닫기
window.print(); // 인쇄

window.alert('알림 문구');
window.confirm('확인 문구');
var answer = window.prompt('질문');

window.innerHeight; // 실제 페이지가 보이는 부분의 해상도
window.innerWidth;
window.pageXOffset; // 스크롤 위치 (IE에서 호환성 문제)
window.pageYOffset;

window.resizeTo(500, 600); // 창 크기를 변경
window.resizeBy(-100, 100); // 창 크기에 주어진 값을 더해서 변경
window.scrollTo(0, 600); // 스크롤을 주어진 좌표로 이동
window.scrollBy(0, 50); // 스크롤을 현재 위치에 주어진 좌표를 더해서 이동

var intervalId = window.setInterval(function(){
    // 1초마다 반복 실행
}, 1000);
window.clearInterval(intervalId);

var timeoutId = window.setTimeout(function(){
    // 1초후에 한번 실행
}, 1000);
window.clearTimeout(timeoutId);


/** window.screen 객체 **/
screen.width; // 디스플레이 해상도
screen.height;


/** window.history 객체 **/
history.length; // 히스토리 갯수
history.back(); // 뒤로가기
history.forward(); // 앞으로
history.go(2); // 앞으로 2번
history.go(-2); // 뒤로 2번


/** window.navigator 객체 **/
navigator.platform; // MacIntel
navigator.userAgent; // Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKi...
navigator.onLine; // true
navigator.language; // en-US
navigator.geolocation.getCurrentPosition(...); // 위치 정보
navigator.getBattery(...) // 배터리
navigator.getUserMedia(...) // 웹캠 및 마이크


/** window.location 객체 **/
// 주소가 http://test.com/some/path?page=3&keyword=test#anchor1 일 때
location.href; // 위의 URL 전체
location.protocol; // http:
location.host; // test.com
location.pathname; // /some/path
location.search; // ?page=3&keyword=test
location.hash; // #anchor1

location.href = 'http://google.com'; // 페이지 이동
location.assign('http://google.com');
location.replace('http://google.com'); // 히스토리에 기록 없이 페이지 이동
location.reload(); // 페이지 새로고침

문서 객체 모델

문서 객체 모델(DOM; Document Object Model)웹 브라우저가 HTML이나 XML 같은 구조화된 문서를 JavaScript로 제어 할 수 있도록 추상화한 객체의 집합입니다. 문서 객체 모델은 window.document를 최상위 노드(Document 노드)로 하는 트리 구조입니다.

DOM 트리DOM 트리

  • 태그
    HTML 문서를 구조화하는 <tagname..>과 같은 문자열

  • DOM
    JavaScript로 제어 할 수 있는도록 객체화된 HTML 문서

  • Node
    DOM 트리를 구성하는 최소 단위

    • Document Node
      문서 자체를 의미하는 최상위 노드 (window.document)
    • Element Node
      태그를 의미하는 노드
    • Attribute Node
      태그 노드의 특성 하나 하나를 의미하는 노드
    • Text Node
      태그 노드의 안에 있는 텍스트

Document 노드

/** Document 노드의 주요 값 **/
document.title; // 문서 제목 (<title> Element의 값)
document.lastModified; // 문서의 최종 수정 일자
document.cookie; // 쿠키
document.referrer; // 레퍼러 URL (어느 페이지에서 왔는지)
document.write("...");


/** Document 노드에서 자식 Element에 접근하기 **/
document.documentElement; // HTML Element
document.head; // HEAD Element
document.body; // BODY Element
document.script; // HTMLCollection of SCRIPT Elements
document.images; // HTMLCollection of IMG Elements
document.forms; // HTMLCollection of FORM Elements
document['FORM_NAME']; // FORM[name='FORM_NAME'] Element 
document.FORM_NAME;

document.getElementsByTagName("div"); // HTMLCollection of DIV Elements
document.getElementsByClassName("someClass"); // HTMLCollection of .someClass Elements
document.getElementById("someId"); // #someId Element
document.querySelectorAll(".some-class > a.hello:hover"); // HTMLCollection of matched Elements
document.querySelector(".some-class > a.hello:hover"); // First matched Element


/** Element의 부모 및 형제 Element 찾기 **/
element.parentElement; // 부모 Element
element.childElementCount; // 자식 Element 갯수
element.children; // HTMLCollection of 자식 Elements
element.firstElementChild; // 첫째 자식 Element
element.lastElementChild; // 마지막 자식 Element
element.nextElementSibling; // 다음 형제 Element
element.previousElementSibling; // 이전 형제 Element

element.getElementsByTagName("div"); // HTMLCollection of DIV Elements in children
element.getElementsByClassName("someClass"); // HTMLCollection of .someClass Elements in children
element.querySelectorAll(".some-class > a.hello:hover"); // HTMLCollection of matched Elements in children
element.querySelector(".some-class > a.hello:hover"); // First matched Element in children

Element 제어하기 (1)

Element 노드

element.tagName; // Element의 태그명(대문자)

/** 내용 제어 **/
element.textContent = "Some Text"; // 짝 태그인 경우
element.innerHTML = "<b>Some Text <div>And other children<p>...</p></div></b>"; // 문자열을 태그로 해석하고 자식으로 삽입
console.log(element.textContent, element.innerHTML); // 물론 내용을 그냥 읽을 수도 있음

/** attribute 제어 **/
element.getAttribute('name');
element.setAttribute('name', 'some-name');
element.removeAttribute('name');

/** Element가 해석한 주요 attribute는 (property) 바로 접근 가능 **/
element.id;
element.type;
element.value;
element.placeholder;
element.checked;
element.disabled;
element.title;
element.src;
element.width/height;

/** 스타일 속성 **/
element.className; // "class1 class2 class3"
element.classList.add("class4");
element.classList.remove("class4");

element.style; // 스타일 속성들에 대해서 HTML/CSS와 다르게 camelCase를 씀
element.style.backgroundColor = '#ff00ff';
element.style.fontSize = '1.2em';

Element 제어하기 (2)

Element 동적으로 생성하기

/** Element 생성은 Document 노드의 메소드를 이용 **/
var h1 = document.createElement("h1");
h1.textContent = "Some Headings...";
h1.style.color = "red";

/** Element를 HTML 문서에 삽입하려면, 이미 존재하는 어떤 Element의 자식으로 삽입 **/
document.body.appendChild(h1);

/** Element를 삭제 할 때는, 부모 Element에서 자식을 삭제 **/
document.body.removeChild(h1);

/** 또는 innerHTML을 이용 할 수도 **/
document.body.innerHTML = "<h1 style=\"color:red\">Some Headings..</h1>";
document.body.innerHTML = "";

Element 제어하기 (3)

색이 바뀌는 공

짜임새 없이 JavaScript만을 이용해서 색이 랜덤하게 바뀌는 공들을 만들어보겠습니다.

이용된 함수설명
setInterval(callback, time)일정한 간격(time)으로 callback을 실행합니다. time은 0.001초 단위입니다.
setTimeout(callback, time)일정한 시간(time) 이후에 callback을 한번 실행합니다. time은 0.001초 단위입니다.
parseInt(value)value를 정수로 리턴합니다. 문자열이나 숫자를 해석합니다. 해석이 불가능하면 NaN이 리턴됩니다.
Math.floor(number)number를 내림해서 리턴합니다. 숫자가 아니면 NaN이 리턴됩니다.
Math.random()0~1 범위에서 임의의 실수를 리턴합니다.

ECMAScript

ECMAScript 또는 ES라고 부르는 JavaScript 언어의 표준이 있습니다. 역사적인 이야기가 있지만 JavaScript의 문법 표준이라고 생각하시면 좋겠습니다. Node.js 같이 로컬에서 컴파일하는 경우나, Chrome 같이 항상 표준을 준수하며, 최신버전으로 자동 업데이트되는 에버그린 웹 브라우저를 이용하는 경우에는, ES의 최신 문법을 이용해도 호환성에 큰 문제가 없습니다. 다만 Internet Explorer로 대표되는 타 웹 브라우저들에서 호환성 문제를 방지하기 위해서는, HTML 문서에서 최신 JavaScript 문법(ES6, ES2016+)을 사용하는 데 고민이 필요합니다.

ECMA스크립트(ECMAScript)는 Ecma 인터내셔널의 ECMA-262 기술 규격에 정의된 표준화된 스크립트 프로그래밍 언어이다. 이 언어는 웹 상에서 널리 쓰이며, 흔히 자바스크립트 또는 J스크립트로도 생각할 수 있지만 두 용어는 특별한 의미 차이가 있다. ECMA스크립트와 자바스크립트, J스크립트의 관계를 이해하기 위해서는 ECMA스크립트의 역사를 알아야 한다… (위키백과)

ES2016+ 브라우저 호환성 테이블

브라우저 환경에서 호환성에 관련 없이 최신 문법을 이용하고 싶은 경우 Babel 등과 같은 Transpiler를 이용 할 수 있습니다. 이 프로그램은 최신 JavaScript 문법으로 작성된 소스코드를 낮은 버전의 JavaScript 문법의 소스코드로 번역하여 웹 브라우저의 호환성 문제를 해결해줍니다.
또는 Shim/Polyfill이라고 불리는 호환성을 위한 script 파일을 HTML 문서에 같이 삽입해서, ES 버전간의 간극을 메우는 방식도 있습니다.

이 강의를 포함한 커리큘럼
저자

김동욱

개발 경력 약 10년, 전문 분야는 웹 및 각종 응용 소프트웨어 플랫폼입니다. Codeflow를 운영하고 있습니다.

2018년 04월 10일 업데이트

지원되지 않는 웹 브라우저거나 예기치 않은 오류가 발생했습니다.