✿∘˚˳°∘°

42일차 : DOM 본문

국비수업/JavaScript

42일차 : DOM

_HYE_ 2023. 1. 26. 20:57

20230126

 

1. DOM(Document Object Model)

HTML에 있는 태그를 객체화하여 자바스크립트에서 다룰 수 있게 한 것

모든 노드객체에 접근할 수 있는 요소와 메소드를 제공(태그하나하나를 노드라고 생각하면된다)

<p>hello</p>
요소노드 : 태그자체 <p></p>
텍스트노드 : 태그에 기록되어있는 문자 hello

- 텍스트 노드를 가지는 태그(h1, p..등) 와 가지지 않는 태그(input, img)가 있음

요소노드 생성 : document.createElement("태그명")
텍스트노드 생성 : document.createTextNode("내용")
태그에 자손노드추가 : 객체명.appendChild(node)

순서 : 요소노드생성 -> 텍스트노드 생성 -> 요소노드에 텍스트노드 추가 -> body내부의 필요한 위치에 요소노드 추가

 

1 - 1 ) 버튼을 클릭하면 텍스트가 생성

<!DOCTYPE html>
<html lang="ko">
<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">
    <title>DOM</title>
    <script src="js/07_dom.js"></script>
</head>
<body>
    <h1>DOM</h1>
    <hr>
    <div id="add-zone"></div>
    <button onclick="func1();">추가하기</button>
    <!--
        자바스크립트를 하게되면 순서를 정해야함
        1. 사용자가 어떤행동을 햇을 때
        -> 추가하기라는 버튼을 클릭하면
        2. 어떤요소에 변화를 일으킬지 
        -> <p>안녕!</p> 태그를 add-zone에 추가
    -->
</body>
</html>
//추가하기 버튼을 클릭하면 동작하는 함수
function func1(){
    //<p>안녕!</p>
    //1. 요소노드 생성
    //p태그 생성
    const p = document.createElement("p"); //<p></p>태그 생성
    //p태그에 들어갈 내용 생성(안녕!)
    //2.텍스트노드 생성
    const text1 = document.createTextNode("안녕!"); //[안녕!]이라는 text를 생성
    //안녕이라는 글씨가 p태그 사이에 들어가야함
    //3. 텍스트노드를 요소노드에 자식으로 추가
    p.appendChild(text1); //<p>안녕!</p> 완성
    //이미 작성되어있는 태그를 가지고오는 방법(id를 이용한 방법)
    const addZone = document.getElementById("add-zone");
    //새로 생성한 p태그를 addZone 자식으로 추가
    addZone.appendChild(p);
}

<div id="add-zone"></div> 사이에 아무것도 없는 모습
추가하기를 누르면 <p>안녕!</p>가 생성된 모습(누를때마다 추가된다)

 

1 - 2 ) 버튼을 클릭하면 이미지가 생성

<body>
    <h1>DOM</h1>
    <hr>
    <div id="add-zone"></div>
    <button onclick="func1();">추가하기</button>
    <button onclick="func2();">이미지추가</button>
</body>
</html>
//이미지추가 버튼을 클릭하면 동작하는 함수
function func2(){
    //<img src="image/dora.png">
    //닫는태그없음 + 글씨없음(src라는 속성을 만들어줘야함)
    //1. 요소노드 생성(img태그를 만들기)
    const img = document.createElement("img"); //<img>태그 만듬
    //2. 속성을 추가(src추가)
    img.src = "image/dora.png"; //<img src = "image/dora.png">
    const addZone = document.getElementById("add-zone");
    addZone.appendChild(img);
}

이미지추가버튼을 누르면 이미지가 <div></div>에 생성된다

 

1 - 3 ) 버튼을 눌러서 비밀번호보기/비밀번호숨기기 - 속성변경

<body>
    비밀번호 입력 : <input type="password" id="pw">
    <button onclick="func3();">비밀번호 보기</button>
    <button onclick="func4();">비밀번호 숨기기</button>
</body>
//비밀번호 보기 클릭시 동작하는 함수
function func3(){
    //id가 pw인 input태그를 가져옴
    const input = document.getElementById("pw");
    //input 태그의 type속성을 text로 변경
    input.type = "text";

}
//비밀번호 숨기기 클릭시 동작하는 함수
function func4(){
    const input = document.getElementById("pw");
    input.type= "password";
}

 

1 - 4 ) 메뉴넣기

<body>
    <div id="test-zone"></div>
    <button onclick="func5();">메뉴넣기</button>
</body>
//메뉴넣기 버튼 클릭시 동작하는 함수
function func5(){
    /*
    <ul class="navi">
        <li>
            <a href="#">메뉴1</a>
        </li>
        <li>
            <a href="#">메뉴2</a>
        </li>
        <li>
            <a href="#">메뉴3</a>
        </li>
        <li>
            <a href="#">메뉴4</a>
        </li>
    </ul>
    */
    const ul = document.createElement("ul"); //<ul></ul>
    //ul.class = "navi"; 클래스의 경우에는 아래 사용 
    //getAttribute(속성이름) : 해당속성에 적용된 값을 가져옴
    //setAttribute*속성이름, 값) : 해당속성에 값으로 대입
    ul.setAttribute("class", "navi");
    const li1 = document.createElement("li"); //<li></li>
    const li2 = document.createElement("li"); //<li></li>
    const li3 = document.createElement("li"); //<li></li>
    const li4 = document.createElement("li"); //<li></li>

    const a1 = document.createElement("a"); //<a></a>
    a1.href = "#"; // <a href="#"></a>
    const text1 = document.createTextNode("메뉴1"); //메뉴1
    a1.appendChild(text1); //<a href="#">메뉴1</a>

    const a2 = document.createElement("a"); //<a></a>
    a2.href = "#"; // <a href="#"></a>
    const text2 = document.createTextNode("메뉴2"); //메뉴2
    a2.appendChild(text2); //<a href="#">메뉴2</a>

    const a3 = document.createElement("a"); //<a></a>
    a3.href = "#"; // <a href="#"></a>
    const text3 = document.createTextNode("메뉴3"); //메뉴3
    a3.appendChild(text3); //<a href="#">메뉴3</a>

    const a4 = document.createElement("a"); //<a></a>
    a4.href = "#"; // <a href="#"></a>
    const text4 = document.createTextNode("메뉴4"); //메뉴4
    a4.appendChild(text4); //<a href="#">메뉴4</a>

    li1.appendChild(a1); //<li><a href="#">메뉴1</a></li>
    li2.appendChild(a2); //<li><a href="#">메뉴1</a></li>
    li3.appendChild(a3); //<li><a href="#">메뉴1</a></li>
    li4.appendChild(a4); //<li><a href="#">메뉴1</a></li>

    ul.appendChild(li1); //<ul><li><a href="#">메뉴1</a></li></ul> 
    ul.appendChild(li2); //<ul><li><a href="#">메뉴1</a></li></ul> 
    ul.appendChild(li3); //<ul><li><a href="#">메뉴1</a></li></ul> 
    ul.appendChild(li4); //<ul><li><a href="#">메뉴1</a></li></ul> 

    const testZone = document.getElementById("test-zone");
    testZone.appendChild(ul);
}

 

1 - 5 ) style변경하기

<head>
	<style>
    	#h2{
        	color: red;
        }
    </style>
</head>
<body>
	<h2 id="h2">테스트 문구</h2>
    <button onclick="func6();">글씨색변경하기</button>
</body>
//글씨색변경하기 클릭 시 동작하는 함수
function func6(){
    //id가 h2인 요소를 가져옴
    const h2 = document.getElementById("h2");
    //해당요소에 css를 변경하는 경우
    //요소객체명.style.css속성이름 = 적용할 값
    h2.style.color = "blue"; //인라인으로 들어감(우선순위상위)
    //속성이름에 대쉬(-)가 들어가는경우 카멜표기법 적용
    //ex. background-color -> backgroundColor
    //ex. text-align -> textAlign
    h2.style.backgroundColor = "yellow"; 
}

인라인style이 우선순위가 높기떄문에 #h2{}가 지워진걸 확인할 수 있다.

 

1 - 6 ) 삭제하기

<body>
	<div>
        <div id="del-div1" class="del-div">삭제용 div1</div>
        <div id="del-div2" class="del-div">삭제용 div2</div>
        <div id="del-div3" class="del-div">삭제용 div3</div>
        <div id="del-div4" class="del-div">삭제용 div4</div>
        <div id="del-div5" class="del-div">삭제용 div5</div>
    </div>
    <button onclick="func7();">div3 삭제</button>
    <button onclick="func8();">div5삭제버튼 활성화</button>
    <button id="btn">div5 삭제</button>
    <button onclick="func9();">del-div 전체삭제</button>
</body>
//div3삭제하기 클릭시 동작하는 함수 
function func7(){
    //삭제하고 싶은 요소를 가져옴
    const div3 = document.getElementById("del-div3");
    //해당요소 삭제
    div3.remove();
}

//div5삭제버튼 활성화 클릭시 동작하는 함수
function func8(){
    //id가 btn버튼을 클릭하면 del-div5이 삭제되는 기능 동작
    //id가 btn을 가져옴
    const btn = document.getElementById("btn");
    //기능을부여할 경우에는 function(){}대입 
    btn.onclick = function(){
        //삭제하고싶은 요소 가져옴
        const div5 = document.getElementById("del-div5");
        div5.remove();
    }
}

//del-div 전체삭제 버튼 클릭시 동작하는 함수
function func9(){
    //클래스 이름으로 요소를 가지고오는경우
    //동일 클래스를 가진 모든요소를 배열로 가지고 옴
    //해당클래스명 요소가 1개여도 무조건 배열로 리턴 
    const divs = document.getElementsByClassName("del-div");
    console.log(divs);
    divs[0].remove();
    console.log(divs); //배열하나가 날아갔기 때문에 0번인덱스에 del-div2가 들어감
    divs[1].remove();  //모든 del-div를 감싸는 div를 만들어서 걔를 삭제하면된다.
    divs[2].remove();
    divs[3].remove();
    divs[4].remove();
    //0번 인덱스인 del-div1이 삭제되어 다른배열들이 한인덱스씩 앞으로옴
    //[0]del-div2 [1]del-div3 [2]del-div4 [3]del-div5
    //그러므로 divs[1].remove();가 실행될 때 del-div3이 삭제되게된다.
    //다시 인덱스가 앞으로 밀리고 [0]del-div2 [1]del-div4 [2]del-div5
    //divs[2].remove();가 실행되면서 del-div5를 삭제하고 divs[3] divs[4]는 존재하지
    //않으므로 del-div2와 del-div4만 남은 채 삭제함수가 종료된다.

/*
    const div1 = document.getElementById("del-div1");
    const div2 = document.getElementById("del-div2");
    const div3 = document.getElementById("del-div3");
    const div4 = document.getElementById("del-div4");
    const div5 = document.getElementById("del-div5");

    div1.remove();
    div2.remove();
    div3.remove();
    div4.remove();
    div5.remove();
*/
}

del-div2의 인덱스번호가 변경된걸 확인할 수 있다.

 

1 - 6 ) 실습 

<!DOCTYPE html>
<html lang="ko">
  <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" />
    <title>Document</title>
    <style>
      table {
        border: 1px solid black;
      }
      th,
      td {
        width: 100px;
        border: 1px solid black;
		text-align:center;
      }
    </style>
  </head>
  <body>
    <h1>DOM 실습</h1>
    <hr />
    <h3>
      문제1. 추가 버튼을 클릭하면 prompt를 이용하여 이름,나이,주소를 입력받은 후
      테이블에 추가
    </h3>
    <table id="exam1">
      <tr>
        <th>이름</th>
        <th>나이</th>
        <th>주소</th>
      </tr>
    </table>
    <button onclick="func1();" class="btn">추가하기</button>
    <hr />
    <br /><br />
    <h3>
      문제2. 추가 버튼을 클릭하면 prompt를 이용하여 이름,나이,주소를 입력받은 후
      테이블에 추가하며 삭제버튼을 함께 추가
    </h3>
    <table id="exam2">
      <tr>
        <th>이름</th>
        <th>나이</th>
        <th>주소</th>
        <th>삭제</th>
      </tr>
    </table>
    <button class="btn">추가하기</button>
    <script src="js/domexam.js"></script>
  </body>
</html>
function func1(){
    // 1. 추가버튼을 클릭하면 prompt를 이용하여 이름/나이/주소 입력
    const name = prompt("이름 입력");
    const age = prompt("나이 입력");
    const addr = prompt("주소 입력");
    // 2. 입력받은 값을 테이블에 추가하는 함수
    /*
    <tr>
        <td>name</td>
        <td>age</td>
        <td>addr</td>
    </tr>
    */
    const tr = document.createElement("tr"); //<tr></tr>
    
    const td1 = document.createElement("td"); //<td></td>
    const tName = document.createTextNode(name);
    td1.appendChild(tName);

    const td2 = document.createElement("td"); //<td></td>
    const tAge = document.createTextNode(age);
    td2.appendChild(tAge);

    const td3 = document.createElement("td"); //<td></td>
    const tAddr = document.createTextNode(addr);
    td3.appendChild(tAddr);

    tr.appendChild(td1);
    tr.appendChild(td2);
    tr.appendChild(td3);

    const exam1 = document.getElementById("exam1");
    exam1.appendChild(tr);
}

/*
function func2(){
    const name = prompt("이름");
    const age = prompt("나이");
    const addr = prompt("주소");

    const tr = document.createElement("tr");

    const td1 = document.createElement("td");
    const tName = document.createTextNode(name);
    td1.appendChild(tName);

    const td2 = document.createElement("td");
    const tAge = document.createTextNode(age);
    td2.appendChild(tAge);

    const td3 = document.createElement("td");
    const tAddr = document.createTextNode(addr);
    td3.appendChild(tAddr);

    const td4 = document.createElement("td");
    const delBtn = document.createElement("button");
    const delBtnText = document.createTextNode("삭제");
    delBtn.appendChild(delBtnText);
    td4.appendChild(delBtn);

    tr.appendChild(td1);
    tr.appendChild(td2);
    tr.appendChild(td3);
    tr.appendChild(td4);

    const exam2 = document.getElementById("exam2");
    exam2.append(tr);
}
*/

const btns = document.getElementsByClassName("btn");

btns[1].onclick = function(){
    const name = prompt("이름");
    const age = prompt("나이");
    const addr = prompt("주소");
    /*
    <tr>
        <td>name</td>
        <td>age</td>
        <td>addr</td>
        <td><button>삭제</button></td>
    </tr>
    */
    const tr = document.createElement("tr");
    //tr.setAttribute("class", "del-tr");

    const nameTd = document.createElement("td");
    const ageTd = document.createElement("td");
    const addrTd = document.createElement("td");
    const delBtnTd = document.createElement("td");
    const delBtn = document.createElement("button");

    const nameText = document.createTextNode(name);
    const ageText = document.createTextNode(age);
    const addrText = document.createTextNode(addr);
    const delBtnText = document.createTextNode("삭제");
    
    nameTd.appendChild(nameText);
    ageTd.appendChild(ageText);
    addrTd.appendChild(addrText);

    delBtn.appendChild(delBtnText);
    delBtnTd.appendChild(delBtn); //순서중요!


    tr.appendChild(nameTd);
    tr.appendChild(ageTd);
    tr.appendChild(addrTd);
    tr.appendChild(delBtnTd);

    delBtn.onclick = function(){
        /*
        const delTr = document.getElementsByClassName("del-tr")
        //배열로 가져오기때문에 삭제도 배열을 삭제해줘야함!
        delTr[0].remove(); */
        tr.remove();
        /*
            <tr></tr> : a1
            <but></but> : b1
            b1.onclick = function(){
                a1.remove();
            }

            <tr></tr> : a2
            <but></but> : b2
            b2.onclick = function(){
                a2.remove();
            }
        */
    }
    const table = document.getElementById("exam2");
    table.appendChild(tr);
}

 

1 - 7 ) innerHTML / innerText / outerHTML

<body>
	<div id="d1" class="dd1" name="name1"><span>첫번째</span><span>입니다.</span></div>
    <div id="d2" class="dd1" name="name1">두번째</div>
    <div id="d3" class="dd2" name="name1">세번째</div>
    <div id="d4" class="dd2" name="name2">네번째</div>
    <button id="btn1" onclick="func1();">버튼1</button>
    <button id="btn2">버튼2</button>
    <button id="btn3">버튼3</button>
    <button id="btn4" onclick="func4();">버튼4</button>
</body>
function func1(){
    //const div1 = document.getElementById("d1");
    //css선택자를 이용해서 요소를 가져오는 방법 - id
    const div1 = document.querySelector("#d1"); //querySelector - 해당하는거 하나만가져옴

    //<div>안녕</div> : innerHTML innerText는 태그사이의 내용(안녕)을 읽어옴
    //innerHTML : 해당요소의 시작태그와 종료태그 사이의 내용을 모두 읽어옴(태그포함)
    //innerText : 해당요소의 시작태그와 종료태그 사이의 내용을 모두 읽어옴(태그제외)
    console.log(div1.innerHTML); 
    console.log(div1.innerText);
    
    //속성값 변경도 가능하다
    //div1.innerHTML = "바뀐데이터"; 
    div1.innerHTML = "<a href='#'>링크</a>"; 
    //innerText로 넣을경우 태그로 동작X 글씨로 동작한다.
    div1.innerText = "<a href='#'>링크</a>"; 
    //글씨만 변경할거면 innerText 태그도 변경할거면 innerHTML사용

    //읽기전용
    //outerHTML : 해당 요소의 시작태그와 종료태그를 포함한 내용을 모두 문자열로 읽어옴
    //단, 수정이 불가능하다
    console.log(div1.outerHTML);
}

//클래스로가져오기
const btn2 = document.querySelector("#btn2");
btn2.onclick = function(){
    //const divs = document.getElementsByClassName("dd2");
    //css선택자를 이용해서 요소를 가져오는 방법 - class
    const divs = document.querySelectorAll(".dd2");//css 선택자형식 그대로 적어줘야함
    console.log(divs[0].innerText);
    console.log(divs[1].innerText);
    divs[0].innerText = "세번째 div 변경~";
    divs[1].innerText = "네번째 div 변경~!!";
    console.log(divs[0].innerText);
    console.log(divs[1].innerText);
}

//name으로 가져오기
const btn3 = document.querySelector("#btn3");
btn3.onclick = function(){
    //const divs = document.getElementsByName("name1"); //s붙어잇으면 배열로가져옴
    const divs = document.querySelectorAll("[name=name1]");
    //글씨색을 빨강으로 변경
    for(let i=0; i<divs.length; i++){
        divs[i].style.color = "red";
    }
    /*
    divs[0].style.color = "red";
    divs[1].style.color = "red";
    divs[2].style.color = "red";
    */
}

function func4(){
    //const divs = document.getElementsByTagName("div");
    const divs = document.querySelectorAll("div");
    //배경색을 노랑색으로 변경
    divs.forEach(function(item, index){
        item.style.backgroundColor = "yellow";
    })
    /*
    for(let i=0; i<divs.length; i++){
        divs[i].style.backgroundColor = "yellow";
    }
    */
}

초기창
최종결과창(모든버튼클릭)

 

1 - 8 ) value(input객체사용)

    <input type="text" name="input1" id="input1" value="초기값"><br>
    <input type="password" name="input2" id="input2"><br>
    <button id="btn5" onclick="func5();">버튼5</button>
    <button id="btn6" onclick="func6();">버튼6</button>
    <button id="btn7"onclick="func7();">버튼7</button>
function func5(){
    const input1 = document.querySelector("#input1");
    const input2 = document.querySelector("#input2");
    //input은 끝나는태그가 없기때문에 innerHTML이 존재하지않음
    //현재 input에 입력되어있는 값은 요소명.value로 가져온다.
    const input1Value = input1.value;
    const input2Value = input2.value;

    console.log(input1Value);
    console.log(input2Value);
}

function func6(){
    const input1 = document.querySelector("#input1");
    const input2 = document.querySelector("#input2");

    const input1Value = input1.value;
    const input2Value = input2.value;

    //input1Value = "값변경"; 이코드는 작동하지X 얘는 데이터를 복사했을뿐이다
    input1.value = "값 변경";
    input2.value = "1234";
}

function func7(){
    const input1 = document.querySelector("#input1");
    const input2 = document.querySelector("#input2");
    input2.type="text";
    input1.setAttribute("readonly", true); //버튼7을 누르면 수정불가가된다.
}

버튼5를 누르면 input에 들어있는 값들이 console에 출력된다.
버튼6을 누르면 value값이 변경된다.
버튼7을 누르면 input1은 변경불가 input2는 text타입으로 변경된다.

 

1 - 9 ) 링크변경하기

    <a href="http://www.naver.com" id="link">네이버로이동</a><br>
    <button id="btn8" onclick="func8();">구글로 이동으로 변경</button>
function func8(){
    const link = document.querySelector("#link");
    link.innerText = "구글로 이동";
    link.href="http://www.google.com";
}

Comments