웹 문서의 모든 요소를 자바스크립트를 이용해 조작할 수 있도록 하는 것을 말한다. 이 DOM은 다음과 같은 계층 구조로 표현된다.
위 그림을 예로 html, head, body, title 등 네모 상자에 들어 있는 것들을 노드 라고 부르고 그 노드들을 연결하는 선들을 가지 라고 부른다.
웹문서의 태그는
요소 노드
태그가 품고 있는 텍스트는 요소 노드의 자식 노드인텍스트 노드
태그의 속성은 요소 노드의 자식 노드 인속성 노드
주석은주석 노드
이 DOM을 통해 다음과 같은 작업을 수행할 수 있다.
DOM 요소를 선택하는 방법에는 6가지가 있다.
document.getElementById("아이디")는 HTML에 부여한 id 속성으로 DOM 요소를 선택하는 방법이다.
한 문서에 id는 유일한 값이기 때문에, elements가 아닌 element로 작성한다.
이 방법은 id 값으로 축약해 작성할 수도 있어, 자주 사용된다.
<body>
<h1 id = "title">This is Title</h1>
<button id="btn">blue</button>
<button><button>
<script>
document.getElementById("title").style.color = "red"; // title이 빨간 색으로 변경
btn.onclick = function(){ // id가 btn인 버튼을 누르면 title이 파란색으로 변경
title.style.color = "blue" // 다른 버튼은 눌러도 title의 색이 변경되지 않음
}
//document.getElementsById("title").style.color = "red"와 title.style.color = "red"는 동일함
</script>
</body>
document.getElementsByTagName("태그이름")는 해당 태그 이름의 요소들을 선택하는 방법이다. 하나의 특정한 요소를 선택하기 위해서는 중괄호 뒤에 인덱스를 추가해주어야 한다.
<!-- 여름의 배경색을 파란색으로 변경-->
<body>
<ul>
<li>봄</li>
<li>여름</li>
<li>가을</li>
<li>겨울</li>
</ul>
<script>
document.getElementsByTagName("li")[1].style.backgroundColor = "blue";
</script>
</body>
document.getElementsByTagName("클래스이름")는 해당 클래스에 속한 요소들을 선택하는 방법이다. 하나의 특정한 요소를 선택하기 위해서는 중괄호 뒤에 인덱스를 추가해주어야 한다.
<!-- class = "red" 맨 첫번째 요소에만 텍스트 컬러 빨강,
class = "blue" 모든 요소에 텍스트 컬러 파랑 -->
<body>
<ul>
<li class="red">봄</li>
<li class="blue">여름</li>
<li class="red">가을</li>
<li class="blue">겨울</li>
</ul>
<script>
document.getElementsByClassName("red")[0].style.color = "red";
document.getElementsByClassName("blue").style.color = "blue";
</script>
</body>
document.getElementsByName("name")은 해당 name 속성값을 가진 요소를 선택하는 방법이다. 하나의 특정한 요소를 선택하기 위해서는 중괄호 뒤에 인덱스를 추가해주어야 한다.
<!-- class = "red" 맨 첫번째 요소에만 텍스트 컬러 빨강,
class = "blue" 모든 요소에 텍스트 컬러 파랑 -->
<body>
<div>
<img src ="#" alt="#" name="photo">
</div>
<script>
document.getElementsByName("photo")[0].src = "#2"; // img src가 #에서 #2로 변경
</script>
</body>
document.querySelector(선택자)는 해당 선택자로 선택되는 요소를 선택하는 방법이다. ID가 아닌 클래스명이나 Tag를 통해 선택할 경우, 가장 위에 있는 요소를 선택한다.
다른 요소를 선택하거나, 모든 요소를 선택하고 싶다면 document.querySelectorAll(선택자)을 이용하면 된다.
<body>
<ul>
<li>HTML</li>
<li class="active">CSS</li>
<li>JavaScript</li>
</ul>
<ol>
<li>HTML</li>
<li class="active">CSS</li>
<li>JavaScript</li>
</ol>
<script>
// 최상위 요소의 li에 스타일 적용 (ul 태그의 첫번째 li에 적용 )
var li = document.querySelector("li");
li.style.color = "red";
//querySelectorAll과 for문은 세트! for문이 없으면 다른 요소에 스타일이 적용되지 않음.
var lis = document.querySelectorAll(".active");
for(var i=0; i < lis.length; i++){
lis[i].style.color = "blue";
}
</script>
HTML 요소를 자바스크립트에서 생성하는 메소드에는 createElement()와 createTextNode(), appendChild(), setAttribute()가 있다.
// <p>안녕하세요</p> 생성하기
var newP = document.createElement("p"); // p태그 추가
var newText = document.createTextNode("안녕하세요"); // 텍스트 노드 추가
newP.appendChild(newText) // 텍스트 노드를 p태그의 자식 노드로 추가
document.body.appendChild(newP); // p태그를 body의 자식 노드로 추가
newP.setAttribute("id", "subtitle");
이벤트란 브라우저에서 사용자의 조작이나 환경의 변화로 벌어진 사건을 말하고, 이러한 이벤트에 즉각적인 반응을 할 수 있게 하는 것을 핸들러라고 부른다.
브라우저에서 발생하는 이벤트에는 5가지가 있다.
| 이벤트 | 이벤트 설명 |
|---|---|
| 윈도우 이벤트 | 브라우저에 변화가 생겼을 때 발생하는 이벤트 |
| 마우스 이벤트 | 사용자가 마우스로 조작했을 때 발생하는 이벤트 |
| 키보드 이벤트 | 사용자가 키보드를 조작했을 때 발생하는 이벤트 |
| 폼 이벤트 | 폼요소 조작에 의해 발생하는 이벤트 |
| 클립보드 이벤트 | 사용자가 복사, 자르기, 붙여넣기를 할 때 발생하는 이벤트 |
첫 번째 방법은 HTML 태그에 직접 이벤트를 넣는 방법이다.
<!--버튼을 누르면 prompt창-->
<button onclick="prompt('나이를 입력하세요')">나이 입력</button>
<!--p에 마우스를 올리면 빨간색, 빠지면 검정색-->
<p onmouseover= "style.color='red'" onmouseout="style.color='black'">안녕하세요</p>
가장 간단한 방법이지만, HTML 코드에 자바스크립트 코드가 추가되어 가독성이 떨어지고, 유지보수도 힘들어진다. 또 하나의 객체에 동일한 이벤트 타입은 중복해서 적용할 수 없다는 단점이 있다.
두 번째 방법은 콜백 함수를 이용해 이벤트를 넣는 방법이다.
<body>
<p id="greeting">안녕하세요</p>
<script>
greeting.onmouseover = function(){
greeting.style.fontSize = "20px";
} // 적용되지 않음
greeting.onmouseover = function(){
greeting.style.color = "red";
} // 적용
greeting.onmouseout = function(){
greeting.style.color = "black";
}
</script>
</body>
이 또한 하나의 객체에 하나의 이벤트 핸들러만 적용할 수 있다는 단점이 있다. 이벤트 타입이 다르다면 적용이 되지만, 이벤트 타입이 같다면 적용되지 않는다.
여기서, 적용되는 이벤트 핸들러는 맨 마지막에 작성된 이벤트 핸들러이다.
마지막은 addEventListener() 메소드를 사용하는 방법이다. 개발자가 가장 추천하는 방법이며, 거의 모든 브라우저에서 지원하는 이벤트 핸들러를 등록하기 위한 메소드이다.
<p id="greeting">안녕하세요</p>
<script>
function fontSize20(){
greeting.style.fontSize = "20px";
}
function fontSize16(){
greeting.style.fontSize = "16px";
}
function colorRed(){
greeting.style.color = "red";
}
function colorBlack(){
greeting.style.color = "black";
}
위의 두 가지 방법과는 다르게 하나의 객체에 여러 이벤트 핸들러를 적용할 수도 있고, 유지보수가 간편하다.
box_over.addEventListener("mouseover", colorPlum); /*마우스 올리면 plum*/
box_over.addEventListener("mouseout", colorPowderblue); /*마우스 빠지면 powder_blue*/
box_enter.addEventListener("mouseenter", colorOrange); /*마우스 올리면 orange*/
box_enter.addEventListener("mouseleave", colorYel); /*마우스 빠지면 yellow*/
box_click.addEventListener("click", colorYelgreen); /*클릭하면 yellowgreen*/
box_click.addEventListener("dblclick", colorPalegreen); /*더블클릭하면 palegreen*/
function colorPlum(){
box_over.style.backgroundColor = "plum";
box_over.innerHTML = "mouseover"
}
function colorPowderblue(){
box_over.style.backgroundColor = "powderblue";
box_over.innerHTML = "mouseout"
}
function colorOrange(){
box_enter.style.backgroundColor = "orange";
box_enter.innerHTML = "mouseenter"
}
function colorYel(){
box_enter.style.backgroundColor = "yellow";
box_enter.innerHTML = "mouseleave"
}
function colorYelgreen(){
box_click.style.backgroundColor = "yellowgreen";
box_click.innerHTML = "click"
}
function colorPalegreen(){
box_click.style.backgroundColor = "palegreen";
box_click.innerHTML = "dblclick"
}
btn.onclick = function(){
box_over.removeEventListener("mouseover", color_plum); // 이벤트리스너를 지우는 메소드
box_over.removeEventListener("mouseout", color_powderblue); // 이벤트리스너를 지우는 메소드
}
over과 out은 자식 요소의 이벤트가 발동하면 부모 요소에 적용한 이벤트까지 함께 발동한다.
바로 위 부모요소에서 끝나는 것이 아니라, 부모요소에 부모요소가 있다면, 그 부모요소에도 이벤트가 발동하고 이는 최상위 요소까지 이어진다. ( = 이벤트 버블링 )
하지만 enter과 leave는 자식 요소의 이벤트가 발동해도 부모 요소의 이벤트는 발동되지 않는다.
즉, over과 out은 자식요소와 부모요소를 독립적으로 본다.
enter과 leave는 자식 요소를 부모요소의 일부분으로 본다.
클릭 이벤트에는 mousedown, mouseup, click, dbleclick 이 있다.
click 이벤트는 mousedown - mouseup - click 순으로 발동
dblclick 이벤트는 mousedown - mouseup - click - mousedown - mouseup - click - dbleclick 순으로 발동
마우스를 누른 상태에서 이벤트 영역에서 벗어나 마우스를 떼면 mouseup과 click 이벤트가 발동하지 않는다.
<body>
<div id="box"></div>
<script>
box.addEventListener("mousedown", colorRed);
box.addEventListener("mouseup", colorYel);
box.addEventListener("click", colorBlue);
function colorRed(){
box.style.backgroundColor = "red";
}
function colorYel(){
box.style.backgroundColor = "yellow";
}
function colorBlue(){
box.style.backgroundColor = "blue";
}
</script>
</body>
박스를 누르면 파란색으로만 바뀌는 것이 아니라, 빨간색 - 노란색 - 파란색 순으로 변경된다.
getAttribute는 문서 객체 내 요소를 선택하고, 그 요소의 속성값을 불러오는 메소드이다.
<body>
<div id="box">
<p id="title" name="title">Title</p>
<img src="img/dog.jpg" alt="#" name="photo"></img>
</div>
<script>
document.getElementsByName("photo").getAttribute("src"); //img/dog.jpg
document.getElementsByName("photo").src; //img/dog.jpg
</script>
</body>
setAttribute는 문서 객체 내 요소를 선택하고, 그 요소의 속성 값을 변경하는 메소드이다.
<body>
<div id="box">
<p id="title" name="title">Title</p>
<img src="img/dog.jpg" alt="#" name="photo"></img>
</div>
<script>
document.getElementsByName("photo").setAttribute("src","img/cat.jpg"); // src속성값이 "img/cat.jpg"로 변경
document.getElementsByName("photo").src = "img/cat.jpg"; // src속성값이 "img/cat.jpg"로 변경
</script>
</body>
회원가입을 할 때 약관 동의 여부를 묻거나, 가입 양식에 입력한 값이 유효한 값인지 검사하기 위해서는 폼의 속성을 제어할 수 있어야 한다. 그리고 그 폼 속성을 제어하기 위해서는 먼저 폼 요소 선택 방법을 알아야 한다.
document.폼명.요소명 을 통해 입력 요소를 선택한다.
<body>
<form action="#" method="get" name="form">
<fieldset>
<legend>회원가입 동의</legend>
<div id="terms">
회사는 법령이 정하는 바에 따라 "회원"의 개인정보를 보호하기 위해 노력합니다. 개인정보의 보호 및 사용에 대해서는 관련법 및 회사의 개인정보취급방침이 적용됩니다.
</div>
<div>
<input type="checkbox" name="accept" id="accept">
<label for="accept">약관 동의합니다.</label>
</div>
<div id="promotion">
<p>광고성 수신 동의</p>
<input type="checkbox" name="all_chk" id="all_chk">
<label for="all_chk">전체선택</label><br>
<input type="checkbox" name="sub_1" id="sub_1">
<label for="sub_1">SMS</label><br>
<input type="checkbox" name="sub_2" id="sub_2">
<label for="sub_2">Email</label><br>
<input type="checkbox" name="sub_3" id="sub_3">
<label for="sub_3">App push</label><br>
</div>
<div>
<input type="submit" value="등록 완료">
<input type="reset" value="등록 취소">
</div>
</fieldset>
</form>
<script>
/*전체 선택 버튼: 체크 >> 전체 선택
전체 선택 버튼: 체크해제 >> 전체 해제 */
document.form.all_chk.onclick=function(){
if(this.checked){
document.form.sub_1.checked=true;
document.form.sub_2.checked=true;
document.form.sub_3.checked=true;
}else{
document.form.sub_1.checked=false;
document.form.sub_2.checked=false;
document.form.sub_3.checked=false;
}
}
/*약관에 동의하지 않으면 (accept를 체크하지 않으면) 약관 동의 알림 + 약관에 포커스 */
document.form.onsubmit = function(){
act = document.form.accept;
if(act.checked == false){
alert("약관에 동의해주세요");
act.focus();
return false;
}
}
</script>
</body>
<body>
<h1><span id="name_place">ㅇㅇㅇ</span>님 전기 자동차 견적</h1>
<form name="form1">
<input type="checkbox" id="opt1" value="250000" onclick="cost()">
<label for="opt1">인조가죽세트 / 250000</label><br>
<input type="checkbox" id="opt2" value="350000" onclick="cost()">
<label for="opt2">네비게이션 / 350000</label><br>
<input type="checkbox" id="opt3" value="440000" onclick="cost()">
<label for="opt3">선루프 / 440000</label><br>
<h3>차량견적</h3>
<input name="total" id="total" value="0">
</form>
<script>
function cost() {
var totalCost = Number(total.defaultValue); //sum 역할
for (var i = 1; i <= 3; i++) {
var option = document.getElementById("opt" + i);
if (option.checked) {
totalCost += Number(option.value)
};
}
total.value = totalCost;
}
var name = "홍길동길동"; //이름
star = function(name){ // 이름 길이 - 1만큼 * 입력
stars = "";
for(i=0; i < name.length - 1; i++){
stars += "*"
}
return stars;
}
var f_name = name.substring(0,1); //성
var secret = star(name); //이름
name_place.innerHTML = f_name + secret;
</script>
</body>
<body>
<h1>Title</h1>
<p id="greeting">안녕하세요</p>
<p id="hello">Hello</p>
<h1></h1>
<script>
let eventList = document.querySelectorAll('p'); // p만 모두 모아 eventList에 저장
eventList.forEach(function(event){
event.addEventListener("mouseover", function(){ // 마우스 올리면 적용할 이벤트
event.style.fontSize = "20px";
event.style.color = "red";
})
event.addEventListener("mouseout", function(){ // 마우스 떼면 적용할 이벤트
event.style.fontSize = "16px";
event.style.color = "black";
})
})
</script>
</body>
<body>
<button onclick = "create_button()">Create Button</button>
<button onclick = "create_text()">Create Text</button>
<button id="create_img">Create Image</button>
<script>
/*createElement("tag name"): 지정한 tag name의 HTML 요소 생성
createTextNode("text"): 텍스트 노드 생성
document.body.appendChild(tag name): 지정한 tag name의 HTML 요소를 body에 추가
parent tag name.appendChild(tag name): 해당 부모 태그 안에 HTML 요소 추가 */
function create_button(){
var br = document.createElement("br");
var btn = document.createElement("button");
var text = document.createTextNode("hello World!");
document.body.appendChild(br); // body에 br 태그 추가
btn.appendChild(text); // btn (button)안에 텍스트 노드 추가
document.body.appendChild(btn); // body에 btn(button) 태그 추가
}
function create_text(){
var h1 = document.createElement("h1");
var text = document.createTextNode("hello World!");
h1.appendChild(text);
document.body.appendChild(h1);
}
create_img.addEventListener("click", (e) => {
var img = document.createElement("img");
var br = document.createElement("br");
img.setAttribute("src", "img/animal/cat.jpg");
img.setAttribute("width", "500px");
document.body.appendChild(br);
document.body.appendChild(img);
})
</script>
</body>