-
문서 객체 모델 (DOM)html, css, js 2023. 3. 1. 20:53
자바스크립트를 사용하는 이유는?
- 어떤 조건에 맞거나, 사용자의 동작이 있을때 웹 문서 전체 또는 일부분이 동작으로 반응하게 하기 위함이다. 이렇게 하려면 웹 문서의 모든 요소를 따로 제어할 수 있어야한다.
DOM(document object model) ?
- DOM 문서객체 모델이란 자바스크립트를 이용하여 웹 문서에 접근하고 제어할 수 있도록 객체를 사용해 웹 문서를 체계적으로 정리하는 방법이다.
- DOM은 웹 문서를 하나의 객체로 정의하고, 웹 문서를 이루는 텍스트나 이미지 표 등 모든 요소도 각각 객체로 정의한다. 즉 웹 문서와 그안의 모든 요소를 객체로 인식하고 처리한다.
DOM tree
DOM은 웹 문서의 요소를 부모 요소와 자식 요소로 구분한다.
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <title>DOM Tree 알아보기</title> </head> <body> <h1>Do it!</h1> <img src="images/doit.jpg" alt="공부하는 이미지"> </body> </html>
이런 코드가 있을떄 html요소는 head,body의 부모 요소이고, 다시 body요소는 h1,img의 부모 요소가 된다. DOM은 문서안 요소뿐만 아니라 각요소에서 사용한 내용과 속성도 자식으로 나타내는데 h1요소의 내용인 "DO it" 은 h1의 자식이되고 src, alt 속성은 img요소의 자식이된다. 이렇게 부모와 자식 구조로 표시하면 마치 나무 형태가 되므로 DOM트리 라고 한다.
- HTML 소스를 코딩할떄는 들여쓰기를 잘해야한다. 그래야 소스만 봐도 HTML DOM의 계층 구조를 머릿속으로 그릴 수 있다.
- DOM트리에서 가지가 갈라져 나간 항목을 노드 라고한다.
- DOM트리의 시작부분인 html노드를 루트라고 한다.
- DOM트리는 기본원칙에 따라 요소노드, 텍스트 노드, 속성 노드, 주석노드 등으로 구분할수있다.
DOM요소에 접근하기
CSS에서는 class , id 태그 등의 스타일을 각각 구별해야 정의해야한다. 이때 class, id 태그 등을 선택자 라고한다.
id선택자로 접근하는 getElementById()
특정한 id가 포함된 DOM요소에 접근할 수 있다.
요소명.getElementById("id명")
document.getElementById("heading")class값으로 접근하는 getElementsByClassName()
지정한 class선택자 이름이 들어 있는 DOM 요소에 접근한다.
중복을 허용하지않는 id 선택자와 다르게, class 선택자는 반환하는 요소가 2개 이상일 수 있다. 그래서 Elements인것
요소명.getElementsByClassName("class명") document.getElementsByClassName("bright")
태그 이름으로 접근하는 getElementsByTagName()
class나 id를 지정하지 않은 DOM요소에 접근할떄 사용한다.
요소명.getElmentsByTagName("태그명") document.getElementByTagName("p")
앞에서 살펴본 getElementById(), getElementsByClassName(), getElementsByTagName()메소드의 반환값은 HTMLElement 객체이다. DOM트리의 텍스트, 속성 노드까지 자유롭게 제어하려면 다음 아래 나오는 메소드를 이용해야한다.
텍스트, 속성 노드에 접근 querySelector(), querySelectorAll()
- 메소드 반환값은 노드이거나, 노드 리스트( 노드를 한꺼번에 여러 개 저장한것으로 배열과 비슷함) 이다.
- id선택자 처럼 반환값이 하나라면 querySelector, 여러값이 한꺼번에 반환될 경우 querySelectorAll
- 선택자를 표시할떄 id 이름 앞에서는 #기호를, class이름 앞에는 . 기호를 붙인다. 태그는 기호 없이 태그명만 쓰면된다.
노드.querySelector(선택자)
노드.querySelectorAll(선택자 또는 태그)
document.querySelector("#heading") // id="heading"인 요소
document.querySelectorAll(".bright") // class="bright"인 요소웹 요소의 내용을 수정하는 innerText, innerHTML 프로퍼티
자바스크립트에선 웹 내용도 수정할 수 있다. innerText는 텍스트 내용을 표시하고 innerHTML은 HTML태그까지 반영하여 표시한다.
innerText, innerHTML 프로퍼티 사용해서 누르는 버튼에 따라 시간을 다르게 표시하는 프로그램
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>innerText, innerHTML 프로퍼티</title> </head> <body> <button onclick="inntext()">innerText로 표시하기</button> <!-- 누르면 inntext()함수 실행--> <button onclick="innhtml()">innerHTML로 표시하기</button><!-- 누르면 innhtml()함수 실행--> <h1>현재 시각: </h1> <div id="current"></div> <script> var now = new Date(); function inntext(){ document.getElementById("current").innerText = now; //id="current"인 요소에 접근하여, now문구 삽입 } function innhtml() { document.getElementById("current").innerHTML = "<em>" + now + "</em>"; } </script> </body> </html>
속성을 가져오거나 수정하는 getAttribute(), setAttribute()
DOM트리에 속성 노드가 추가되면서 속성값이 저장된다. 이때 속성에 접근하려면 getAttribute()메소드를 사용하고, 접근한 속성의 값을 바꾸려면 setAttribute()메소드를 사용한다.
getAttribute("속성명") setAttribute("속성명","값")
getAttribute 이용하여 큰 이미지를 클릭하면 그 이미지의 경로 속성을 가져와 알림창에 표시해보자
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>DOM</title> <link rel="stylesheet" href="./poster.css"> </head> <body> <div id="container"> <h1 id="heading">에디오피아 게뎁</h1> <div id="prod-pic"> <img src="./믿음1.jpeg" alt="에디오피아 게뎁" id="cup" width="200" height="200" onclick="displaySrc()"> //클릭하면 displaySrc()함수실행 <div id="small-pic"> <img src="./믿음2.jpeg" class="small"> <img src="./믿음3.jpeg" class="small"> <img src="./믿음4.jpeg" class="small"> </div> </div> <div id="desc"> <ul> <li>상품명 : 에디오피아 게뎁</li> <li class="bluetext">판매가 : 9,000원</li> <li>배송비 : 3,000원<br>(50,000원 이상 구매시 무료)</li> <li>적립금 : 180원(2%)</li> <li>로스팅 : 2019.06.17</li> <button>장바구니 담기</button> </ul> <a href="#" id="view">상세 설명 보기</a> </div> <div id="detail"> <hr> <h2>상품 상세 정보</h2> <ul> <li>원산지 : 에디오피아</li> <li>지 역 : 이르가체프 코체레</li> <li>농 장 : 게뎁</li> <li>고 도 : 1,950 ~ 2,000 m</li> <li>품 종 : 지역 토착종</li> <li>가공법 : 워시드</li> </ul> <h3>Information</h3> <p>2차 세계대전 이후 설립된 게뎁농장은 유기농 인증 농장으로 여성의 고용 창출과 지역사회 발전에 기여하며 3대째 이어져 내려오는 오랜 역사를 가진 농장입니다. 게뎁 농장은 SCAA 인증을 받은 커피 품질관리 실험실을 갖추고 있어 철처한 관리를 통해 스페셜티커피를 생산합니다.</p> <h3>Flavor Note</h3> <p>은은하고 다채로운 꽃향, 망고, 다크 체리, 달달함이 입안 가득.</p> </div> </div> <script> function displaySrc() { var cup = document.querySelector("#cup"); alert("이미지 소스 : " + cup.getAttribute("src")); } </script> </body> </html>
setAttribute() 이용하여 작은 이미지를 클릭했을 떄 위 큰 이미지 자리에 표시되도록 만들기
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>DOM</title> <link rel="stylesheet" href="./poster.css"> </head> <body> <div id="container"> <h1 id="heading">에디오피아 게뎁</h1> <div id="prod-pic"> <img src="./믿음1.jpeg" alt="에디오피아 게뎁" id="cup" width="200" height="200"> <div id="small-pic"> <img src="./믿음2.jpeg" class="small"> <img src="./믿음3.jpeg" class="small"> <img src="./믿음4.jpeg" class="small"> </div> </div> <div id="desc"> <ul> <li>상품명 : 에디오피아 게뎁</li> <li class="bluetext">판매가 : 9,000원</li> <li>배송비 : 3,000원<br>(50,000원 이상 구매시 무료)</li> <li>적립금 : 180원(2%)</li> <li>로스팅 : 2019.06.17</li> <button>장바구니 담기</button> </ul> <a href="#" id="view">상세 설명 보기</a> </div> <div id="detail"> <hr> <h2>상품 상세 정보</h2> <ul> <li>원산지 : 에디오피아</li> <li>지 역 : 이르가체프 코체레</li> <li>농 장 : 게뎁</li> <li>고 도 : 1,950 ~ 2,000 m</li> <li>품 종 : 지역 토착종</li> <li>가공법 : 워시드</li> </ul> <h3>Information</h3> <p>2차 세계대전 이후 설립된 게뎁농장은 유기농 인증 농장으로 여성의 고용 창출과 지역사회 발전에 기여하며 3대째 이어져 내려오는 오랜 역사를 가진 농장입니다. 게뎁 농장은 SCAA 인증을 받은 커피 품질관리 실험실을 갖추고 있어 철처한 관리를 통해 스페셜티커피를 생산합니다.</p> <h3>Flavor Note</h3> <p>은은하고 다채로운 꽃향, 망고, 다크 체리, 달달함이 입안 가득.</p> </div> </div> <script> var cup = document.querySelector("#cup"); var smallPics = document.querySelectorAll(".small"); for(let i = 0; i < smallPics.length; i++) { smallPics[i].addEventListener("click", changePic); } function changePic() { var newPic = this.src; cup.setAttribute("src", newPic); } </script> </body> </html>
DOM에서 이벤트 처리하기
1. DOM 요소에 함수 직접 연결하기
img요소를 가져와 변수에 저장한 후 onclick을 사용해 변수에 이벤트 처리기를 직접 연결한다.
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>DOM event 객체</title> <style> #container { width:300px; margin:10px auto; } </style> </head> <body> <div id="container"> <img src="images/cup-1.png" id="cup"> </div> <script> var cup = document.querySelector("#cup"); // id = cup인 요소를 가져옴 cup.onclick = function(){ alert("이미지를 클릭했습니다"); } </script> </body> </html>
2. 함수 이름을 사용해 연결하기
이벤트가 발생했을때 실행할 함수를 따로 정의해 놓았다면 함수 이름을 사용해 연결할수있다. ()괄호를 추가하지 않는다.
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>DOM event 객체</title> <style> #container { width:300px; margin:10px auto; } </style> </head> <body> <div id="container"> <img src="images/cup-1.png" id="cup"> </div> <script> var cup = document.querySelector("#cup"); // id = cup인 요소를 가져옴 cup.onclick = changePic; // cup을 클릭하면 changePic 함수 실행 function changePic() { cup.src = "images/cup-2.png"; } </script> </body> </html>
DOM의 event 객체 알아보기
DOM에는 이벤트 정보를 저장하는 event객체가 있다. 이 객체에는 웹 문서에서 이벤트가 발생한 요소가 무엇인지, 어떤 이벤트가 발생했는지 등의 정보가 들어있다.
https://developer.mozilla.org/ko/docs/Web/API/Event#%EC%86%8D%EC%84%B1
Event - Web API | MDN
Event 인터페이스는 DOM 내에 위치한 이벤트를 나타냅니다.
developer.mozilla.org
다음은 이미지에서 발생한 이벤트의 유형과 위치를 알림창으로 보여주는 예제이다. DOM요소에 함수를 직접연결하였고, event객체를 함수의 인수로 사용하였다.
- event.type : 발생한 이벤트 이름을 반환한다.
- evnet.pageX : 현재 문서 기준으로 이벤트가 발생한 가로 위치를 반환한다.
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>DOM event 객체</title> <style> #container { width:300px; margin:10px auto; } </style> </head> <body> <div id="container"> <img src="images/cup-1.png" id="cup"> </div> <script> var cup = document.querySelector("#cup"); // id = cup인 요소를 가져옴 cup.onclick = function(event) { alert("이벤트 유형: " + event.type + ", 이벤트 발생 위치 : " + event.pageX + "," + event.pageY); } </script> </body> </html>
만약 이벤트가 발생한 대상에 접근하려면 이벤트 처리기에서 this 예약어를 사용하면된다.
다음은 this예약어를 이용해 이미지를 클릭하면 알림 창에 경로가 나타는 프로그램이다.
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>DOM event 객체</title> <style> #container { width:300px; margin:10px auto; } </style> </head> <body> <div id="container"> <img src="images/cup-1.png" id="cup"> </div> <script> var cup = document.getElementById("cup"); cup.onclick = function(event) { alert("클릭한 이미지 파일 : " + this.src); } </script> </body> </html>
addEventListener() 메소드
지금까지 살펴본 이벤트 처리기는 한 요소에 하나의 이벤트 처리기( ex. onclick)만 연결할 수 있었다.
addEventListener()메소드와 event 객체를 사용하면 한 요소에 여러 이벤트 처리기를 연결해 실행할 수 있다.
요소.addEventListener(이벤트, 함수, 캡처 여부); 이벤트 : 이벤트 유형을 지정한다, on을 붙이지 않고 쓴다. 함수 : 이벤트가 발생하면 실행할 명령이나 함수를 지정한다. 여기서 함수를 정의할떄는 event객체를 인수로 받는다. 캡처 여부 : 이벤트를 캡처하는지 여부를 지정하며 기본값은 false, 이벤트 캡처링은 DOM부모 노드에서 자식 노드로 전달되는것이고 이벤트 버블링(false)은 DOM 자식 노드에서 부모 노드로 전달되는 것이다.
다음은 이미지 위로 마우스 포인터를 올려놓으면 다른 이미지로 바뀌었다가 내려놓으면 다시 원래 이미지로 돌아오는 예제이다.
addEventListener()메소드를 사용하여 changePic()함수와 originPic()함수를 이벤트 처리기로 사용한다.
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>DOM event 객체</title> <style> #container { width:300px; margin:10px auto; } </style> </head> <body> <div id="container"> <img src="images/easys-1.jpg" id="cover"> </div> <script> var cover = document.getElementById("cover"); cover.addEventListener("mouseover",changePic, false); cover.addEventListener("mouseout",originPic, false); function changePic() { cover.src = "images/easys-2.jpg"; } function originPic() { cover.src = "images/easys-1.jpg"; } </script> </body> </html>
위 코드를 메소드 안에서 함수를 선언하는 방식으로 수정할수있다, 동일하게 동작한다.
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>DOM event 객체</title> <style> #container { width:300px; margin:10px auto; } </style> </head> <body> <div id="container"> <img src="images/easys-1.jpg" id="cover"> </div> <script> var cover = document.getElementById("cover"); cover.addEventListener("mouseover",function() { cover.src = "images/easys-2.jpg"; }); cover.addEventListener("mouseout", function() { cover.src = "images/easys-1.jpg"; }); </script> </body> </html>
CSS 속성에 접근하기
자바스크립트를 이용하면 스타일 속성값을 가져와 그 값을 원하는 대로 수정할 수 있다.
CSS속성에 접근하려면 해당 스타일이 적용된 HTML 요소 다음에 예약어 style을 쓰고 속성을 적는다.
예를 들어 id가 desc인 요소의 글자를 파란색으로 변경하는 예이다.
document.getElementById("desc").style.color = "blue";
이렇게 color처럼 한 단어인 속성명은 그대로 사용하면 되지만 background-color처럼 중간에 하이픈이있는 속성은 backgroundColor로 표기해야한다.
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>DOM CSS</title> <style> #container { width:400px; margin:50px auto; text-align: center; } #rect { width:100px; height:100px; border:1px solid #222; margin:30px auto; transition: 1s; } </style> </head> <body> <div id="container"> <p>도형 위로 마우스 포인터를 올려놓으세요.</p> <div id="rect"></div> </div> <script> var myRect = document.querySelector("#rect"); myRect.addEventListener("mouseover", function() { // mouseover 이벤트 처리 myRect.style.backgroundColor = "green"; // myRect 요소의 배경색 myRect.style.borderRadius = "50%"; // myRect 요소의 테두리 둥글게 처리 }); myRect.addEventListener("mouseout", function() { // mouseout 이벤트 처리 myRect.style.backgroundColor = ""; // myRect 요소의 배경색 지우기 myRect.style.borderRadius = ""; // myRect 요소의 테두리 둥글게 처리 안 함 }); </script> </body> </html>
라이트 박스 효과 만들기
-> 사진을 클릭하면 전면에 나타낸 후 주변을 어둡게 처리하여 시선을 집중시키는 효과
1. 프로그램을 짜기 전엔 흐름을 정리할 필요가있음
1. 섬네일 이미지 6개를 화면에 보여준다 2. 섬네일 이미지 가운데 하나를 클릭하면 그 이미지를 라이트 박스 영역에 표시하고 화면에 나타나게 한다. 3. 화면에 나타난 라이트 박스 영역을 클릭하면 다시 라이트 박스를 감춘다
2. 사용할 요소 가져오기
- 섬네일 이미지인 pic 요소를 모두 가져온다.
- 라이트 박스를 화면에 표시하거나 감추려면 lightbox 요소를 가져오고,
- 큰 이미지를 표시할 수 있도록 lightboxImage요소도 가져온다
3. 함수 작성하기
- 섬네일 이미지를 클릭하면 실행할 showLightbox()함수를 작성한다. ( 클릭한 섬네일 이미지의 큰 이미지 파일 경로를 가져와서 라이트 박스에 있는 이미지의 파일 경로를 바꿔준다)
- this 예약어는 클릭한대상(섬네일 이미지)의 속성값을 가져오는 역할을 한다.
4. 라이트 박스 감추기
- 화면 아무곳이나 클릭했을때 즉 라이트 박스를 클릭하면 라이트 박스를 닫는다.
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width"> <title>라이트박스</title> <link rel="stylesheet" href="css/lightbox.css"> </head> <body> <div class="row"> <ul> <!-- src 이미지는 섬네일 이미지 / data-src 라이트 박스에서 보여줄 이미지--> <li><img src="images/tree-1-thumb.jpg" data-src="images/tree-1.jpg" class="pic"></li> <li><img src="images/tree-2-thumb.jpg" data-src="images/tree-2.jpg" class="pic"></li> <li><img src="images/tree-3-thumb.jpg" data-src="images/tree-3.jpg" class="pic"></li> <li><img src="images/tree-4-thumb.jpg" data-src="images/tree-4.jpg" class="pic"></li> <li><img src="images/tree-5-thumb.jpg" data-src="images/tree-5.jpg" class="pic"></li> <li><img src="images/tree-6-thumb.jpg" data-src="images/tree-6.jpg" class="pic"></li> </ul> </div> <div id="lightbox"> <img src="images/tree-1.jpg" alt="" id="lightboxImage"> </div> <script> var pics = document.getElementsByClassName("pic"); // .pic인 요소들을 가져와 pics 라는 변수에 저장. querySelectorAll(".pic")도 가능 var lightbox = document.getElementById("lightbox"); // 라이트 박스. querySelector("#lightbox")도 가능 var lightboxImage = document.getElementById("lightboxImage"); // 라이트 박스 안의 이미지. querySelector("#lightboxImage")도 가능 for (i=0; i<pics.length; i++) { pics[i].addEventListener("click", showLightbox); //pics 배열의 i번째 요소를 클릭할 경우 showLightbox 함수를 실행함 } function showLightbox() { var bigLocation = this.getAttribute("data-src"); // 섬네일 이미지 속성값을 가져옴 lightboxImage.setAttribute("src", bigLocation); // 라이트 박스의 이미지 경로를 수정함 lightbox.style.display = "block"; // 라이트박스 이미지를 화면에 표시 } lightbox.onclick = function() { //lightbox를 클릭했을떄! lightbox.style.display = "none"; // lightbox 요소를 화면에서 감춤 } </script> </body> </html>
.row { width:420px; margin:0 auto; } .row ul { list-style:none; margin:0; padding:0; } .row ul li { display:inline-table; } /* 라이트 박스 스타일 */ #lightbox { position: fixed; /* 위치 고정 */ width:100%; /* 너비 */ height:100%; /* 높이 */ background-color:rgba(0,0,0,0.7); /* 배경색 */ top:0; /* 시작 위치 - 위쪽 끝 */ left:0; /* 시작 위치 - 왼쪽 끝 */ display:none; /* 화면에서 감추기 */ } /* 라이트 박스 안의 이미지 */ #lightbox img { position:absolute; /* top, left에 의해 위치 지정 */ top:50%; /* 위쪽에서 50% 부터 */ left:50%; /* 왼쪽에서 50% 부터 */ transform:translate(-50%, -50%); /* 요소를 화면 중앙에 표시하기 위해 이동 */ border:5px solid #eee; /* 이미지 테두리 */ }
DOM에서 노드 추가. 삭제하기
- DOM에서 새로운 노드를 만들어 추가하거나 삭제하려면 노드 리스트를 사용해야한다.
- DOM에 접근할떄 querySelectorAll() 메소드를 사용하면 노드를 한꺼번에 여러개 가져 올수 있다. 이때 노드 정보를 여러개 저장한것이 노드 리스트이다. 이처럼 노드 리스트란? 노드를 여러개 저장한 데이터 형태를 말한다.
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Web Programming</title> <link rel="stylesheet" href="css/nodelist.css"> </head> <body> <h1>Web Programming</h1> <ul id="itemList"> <li>HTML</li> <li>CSS</li> <li>Javascript</li> </ul> </body> </html>
노드 리스트 형태의 li 요소들 노드 리스트는 배열과 비슷해서 인덱스 번호로 특정 위치 노드에 접근할 수 있다.
새로운 노드를 추가 할땐, 웹 문서에 어떤 소스를 추가할지 먼저 생각하고, 그에 따라 요소 노드나 텍스트, 속성 노드 등을 만들어야한다.
예를 들어 <img> 요소로 추가한다면 <img>태그의 요소 노드와 속성에 해당하는 src, alt 노드도 추가해야한다. 이밖에도 사용하는 속성에따라 더 많은 노드가 추가된다.
텍스트 노드를 사용하는 새로운 요소 추가하기
[더보기] 링크를 클릭하면 그 아래에 간단한 텍스트가 표시되는 스크립트 소스를 작성해보겠다.
문서에서는 단순히 <p>태그 하나 추가된걸로 보이지만, DOM에선 여러 단계가 필요하다.
1. 요소 노드 만들기 - createElement()
DOM에 새로운 요소를 추가할때 가장 먼저 할 일은 요소 노드를 만드는 것. 이떄 사용하는 메소드는 createElement() 인데 괄호 안에 해당하는 요소 노드를 만들면 된다.
예를들어 p요소를 새로 만든다면 var newP = document.createElement("p");
하지만 createElement()메소드는 새로운 노드를 만들 뿐, 아직 웹 문서에 새로운 노드를 추가한 것은 아니다.
2. 텍스트 노드 만들기 - createTextNode()
새로운 요소 노드를 만들었다면 그다음은 내용을 담는 텍스트 노드를 만든다.
새롭게 만든 p 요소에 들어갈 텍스트 노드를 변수를 저장 var txtNode = document.createTextNode("DOM은 document object model 이다");
3. 자식 노드 연결하기 - appendChild()
p노드와 텍스트 노드를 만들었다. 이제 이 둘을 부모노드와 자식 노드로 연결해주어야한다.
이떄 appendChild()메소드를 사용해서 연결하는 노드는 자식 노드 중 맨 끝에 추가된다.
부모노드.appendChild(자식코드) newP.appendChild(txtNode); //텍스트 노드를 p노드의 자식 요소로 연결한다, document.getElementById("info").appendChild(newP); // p노드를 <div id="info"></div> 의 자식노드로 연결한다.
4. 전체 소스 코드 완성하기
더보기를 누르면 p태그가 생성된다.
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <title>DOM</title> <style> #container{ width:500px; margin:10px auto; padding:20px; } #info { margin-top:20px; } </style> </head> <body> <div id="container"> <h1>DOM을 공부합시다</h1> <a href="#" onclick="addP(); this.onclick='';">더 보기</a> <!-- onclick=addP(); 클릭하면 p태그 생성함 this.onclick=''; addP()함수가 한번만 실행되도록 하는 장치--> <div id="info"></div> </div> <script> function addP() { var newP = document.createElement("p"); var txtNode = document.createTextNode("DOM은 Document Object Model의 줄임말입니다."); newP.appendChild(txtNode); document.getElementById("info").appendChild(newP); } </script> </body> </html>
속성값이 있는 새로운 요소 추가하기
HTML 태그에서는 여러 가지 속성을 사용해서 웹 요소를 제어한다. 따라서 새로운 요소를 만들면 그와 관련된 속성 노드도 만들어서 자식 노드로 연결해야한다.
앞의 예제에 이어 [더 보기] 링크를 클릭하면 그아래에 텍스트 + 이미지까지 표시되는 스크립트 소스를 추가로 작성해 보자. 웹 문서에서 이미지를 보여주려면 img요소 노드를 추가한 후 src 속성 노드를 만들어 자식 노드로 연결해야한다.
1. 요소 노드 만들기 - createElement()
var newImg = document.createElement("img");
2. 속성 노드 만들기 - createAttribute()
var srcNode = document.createAttribute("src"); var altNode = document.createAttribute("alt"); srcNode.value = "./믿음.jpeg" //src 속성값 지정 altNode.value = "돔 트리 예제 이미지" // alt 속성값 지정
3. 속성 노드 연결하기 - setAttributeNode()
속성 노드 2개를 img 요소 노드의 자식으로 연결해보자
이떄 추가할 속성이 이미 요소 노드에 들어있다면 기존 속성 노드를 새 속성 노드로 대체한다.
newImg.setAttributeNode(srcNode); newImg.setAttributeNode(altNode);
4. 자식 노드 연결하기 - appendChild()
img 요소를 <div id="info"></div>위치에 자식 요소로 추가한다.
document.getElementById("info").appendChild(newImg);
5. 전체 소스 코드 완성하기
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <title>DOM</title> <style> #container{ width:500px; margin:10px auto; padding:20px; } #info { margin-top:20px; } </style> </head> <body> <div id="container"> <h1>DOM을 공부합시다</h1> <a href="#" onclick="addContents(); this.onclick='';">더 보기</a> <div id="info"></div> </div> <script> function addContents() { var newP = document.createElement("p"); var txtNode = document.createTextNode("DOM은 Document Object Model의 줄임말입니다."); newP.appendChild(txtNode); var newImg = document.createElement("img"); var srcNode = document.createAttribute("src"); var altNode = document.createAttribute("alt"); srcNode.value = "./믿음1.jpeg"; altNode.value = "돔 트리 예제 이미지"; newImg.setAttributeNode(srcNode); newImg.setAttributeNode(altNode); document.getElementById("info").appendChild(newP); document.getElementById("info").appendChild(newImg); } </script> </body> </html>
텍스트 필드에 입력한 값을 화면에 표시하기
- 텍스트 필드에 입력한 내용을 새로운 노드로 만들어 화면에 표시해 보자!
- 새로만들 요소는 <ul>태그 사이 들어갈 li 요소 노드이다. 텍스트 필드에 입력한 값을 가져와 새로운 노드를 만들고 li 요소 노드에 자식 노드로 추가하면 된다.
- <button>태그에 return false를 추가하는 이유 : 버튼의 기본 기능인 submit 역할을 취소하기 위한 것이다. 이 기능을 취소하지 않으면 함수를 실행하지 않고 기본 기능을 먼저 실행한다. 기본기능을 끄고 함수만 실행하라고 알려주기 위해 작성하는 구문이다.
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Web Programming</title> <link rel="stylesheet" href="./poster.css"> </head> <body> <div id="container"> <h1>Web Programming</h1> <p>공부할 주제를 기록해 보세요</p> <form action=""> <input type="text" id="subject" autofocus> <!-- 텍스트 필드 id ="subject"--> <button onclick="newRegister(); return false;">추가</button> </form> <hr> <ul id="itemList"></ul> </div> <script> function newRegister(){ var newItem = document.createElement("li"); //li요소 노드 만든다. var subject = document.querySelector("#subject"); //텍스트 필드를 가져온다. var newText = document.createTextNode(subject.value); // 택스트 필드의 필드값을 텍스트 노드로 만든다. newItem.appendChild(newText); // li요소 - 텍스트 노드 연결 var itemList = document.querySelector("#itemList"); //부모 노드를 가져온다 ul itemList.appendChild(newItem); // ul노드에 li 노드를 연결 subject.value =""; //다음 입력을 위해 텍스트 필드 값 초기화 } </script> </body> </html>
만약 위 예제에서 마지막에 입력한 값을 맨위에 나타내고 싶다면?
itemList.appendChild(newItem); -> itemList.insertBefore(newItem, itemList.childNodes[0]); 으로 수정해주면된다,
노드 삭제하기
노드를 삭제할때 기억해 둘 것은 반드시 부모 노드에서 자식 노드를 삭제해야한다는 것이다. 그래서 삭제해야할 노드가 잇다면 부모 노드를 먼저 찾아야 한다.
parentNode 프로퍼티
현재 노드의 부모 노드에 접근해서, 부모 노드의 요소 노드를 반환한다.
노드.parentNode
실행하면 li노드의 부모 노드인 ul 노드가 보인다. document.querySelectorAll("li")[1].parentNode
removeChild() 메소드
자식 노드를 삭제한다.
부모노드.removeChild(자식노드)
li노드를 삭제하려면 lis노드의 부모 노드에서 삭제해야하므로 다음과 같이 작성한다. li.parentNode.removeChild(li) li.parentNode -> ul노드 ul.removeChild(li)와 같음
텍스트 필드에 입력하면 p태그를 추가해주는 위예제에서 입력한 항목 p태그를 클릭하면 삭제되게 구현.
1. 입력한 텍스트를 가져 온 후 거기에서 click이벤트가 발생하면 그 항목의 부모 노드를 찾아서 li 요소를 삭제하라고 한다.
2. 노드 리스트에 있는 요소 전체를 반복하면서 click이벤트가 발생하면 실행할 함수를 연결한다
3. 부모 노드가 있을떄만 부모 노드에서 현재 객체를 삭제할수있게끔 함수를 구현한다.
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Web Programming</title> <link rel="stylesheet" href="./poster.css"> </head> <body> <div id="container"> <h1>Web Programming</h1> <p>공부할 주제를 기록해 보세요</p> <form action=""> <input type="text" id="subject" autofocus> <!-- 텍스트 필드 id ="subject"--> <button onclick="newRegister(); return false;">추가</button> </form> <hr> <ul id="itemList"></ul> </div> <script> function newRegister(){ var newItem = document.createElement("li"); //li요소 노드 만든다. var subject = document.querySelector("#subject"); //텍스트 필드를 가져온다. var newText = document.createTextNode(subject.value); // 택스트 필드의 필드값을 텍스트 노드로 만든다. newItem.appendChild(newText); // li요소 - 텍스트 노드 연결 var itemList = document.querySelector("#itemList"); //부모 노드를 가져온다 ul itemList.appendChild(newItem); // ul노드에 li 노드를 연결 subject.value =""; //다음 입력을 위해 텍스트 필드 값 초기화 var items = document.querySelectorAll("li");//모든 li 항목 가져오기 for(i=0;i<items.length;i++){ items[i].addEventListener("click",function(){ if(this.parentNode) //부모 노드가 있다면 this.parentNode.removeChild(this); // 부모 노드에서 자식노드 삭제 }); } } </script> </body> </html>
마무리문제 1
1. querySelectorAll 사용
2. 노드 리스트 전체를 반복하면서 click이벤트가 발생할때 사용할 함수 연결
3. 부모.parentNode 와 js에서 .style.color 등으로 CSS적용
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>연습문제 1</title> <style> ul{ list-style: none; } li { font-size:20px; line-height: 35px; } .check { color:#ccc; font-size:20px; margin-right:25px; } .check:hover { color:#222; } </style> </head> <body> <h1>할 일 목록</h1> <ul> <li><span class="check">✓</span>할 일 1 </li> <li><span class="check">✓</span>할 일 2 </li> <li><span class="check">✓</span>할 일 3 </li> <li><span class="check">✓</span>할 일 4 </li> <li><span class="check">✓</span>할 일 5 </li> </ul> <script> var checks = document.querySelectorAll(".check");// 체크 표시 부분을 가져와 노리스트를 만든다. for(var i = 0; i < checks.length; i++) { //addEventListener 이벤트 처리기 이용하여, "click"이벤트가 발생하면 실행할 함수를 연결한다. checks[i].addEventListener("click", function() { this.parentNode.style.color = "#ccc"; //노드.parentNode 현재노드인 span태그의 부모노드인 li태그에 접근하여 색상을 바꾼다. this.parentNode.style.textDecoration="line-through"; //위와 같은 방법으로 밑줄 스타일을 가로줄 line-through로 바꾼다. }); } </script> </body> </html>
마무리문제 2
행과 열의 개수를 입력한 값에 따라 표를 그리는 소스를 작성해보자!
1. from 태그에서 input태그를 이용하여 행과 열 정보를 받는다.
2. 버튼 태그에 onclick="drawTabe()" 함수를 추가하여 클릭시 js에 구현해놓은 함수를 실행하게 만든다. return false; 구문을 추가하여 submit동작이 아닌 함수 동작을 하게 한다.
3. drawTable()함수를 통해 만든 표를 표시할 div id="content" 태그를 만든다.
4. drawTable()함수를 구현한다.
<함수 구현>
querySelector를 이용해 노드 형태로 행과 열 값을 가져온다. -> createElement를 이용해 table태그를 만든다. -> 중첩 반복문과 createElement를 이용해 입력받은 row(tr)에 따른 col(td)를 만든다 -> createTextNode를 이용해 텍스트 노드를 만든다. -> appendChild()이용해 텍스트노드와 td요소 노드를 연결한다. -> tr요소 노드와 td요소 노드를 연결한다. -> table요소와 tr요소 노드를 연결한다.
5. 전에 만든 div id="content"요소를 가져와 table과 연결한다.
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>연습문제 2</title> <style> form { margin-bottom:30px; } input[type="text"] { width:30px; height:20px; text-align: center; } button { margin-left:10px; } table { width:300px; } table, td { /* table과 td(셀) 테두리와, 테두리 합칩 border-collapse */ border:1px solid #ccc; border-collapse: collapse; } td { padding:10px; } </style> </head> <body> <form> <!-- 폼태그 이용하여 값 받기--> <input type="text" id="rCount" value="1">행 <input type="text" id="cCount" value="1">열 <button onclick="drawTable(); return false;">작성</button> <!--누르면 drawTable()함수 실행--> </form> <div id="contents"></div> <!-- js로 만든 테이블을 표시할 곳 --> <script> function drawTable() { var rCount = document.querySelector("#rCount").value; var cCount = document.querySelector("#cCount").value; var newTable = document.createElement("table"); for(i = 0; i < rCount; i++) { var newRow = document.createElement("tr"); for(j = 0; j < cCount; j++) { var newCell = document.createElement("td"); var cellText = document.createTextNode(i + ", " + j); newCell.appendChild(cellText); newRow.appendChild(newCell); } newTable.appendChild(newRow); } var contents = document.querySelector("#contents"); contents.appendChild(newTable); } </script> </body> </html>
'html, css, js' 카테고리의 다른 글
[front-end] 영화 소개 사이트 만들기 (4) 2023.03.14 DOM 정리 (0) 2023.03.01 [js] 객체, 프로퍼티, 메소드 (0) 2023.02.27 [js] 함수/ 이벤트 (1) 2023.02.22 [js] 자바 스크립트 기본 문법(변수/ 자료형/연산자/조건문/반복문) (0) 2023.02.21