[JavaScript ES6] Dom

Sooooooah·2023년 4월 25일

javaScript ES6

목록 보기
8/8

DOM

Document Object Model : 웹의 문서와 웹의 태그와 관련된 객체

HTML 요소들의 구조화된 표현

DOM 객체 구조 = ‘노드 트리’ : 부모 가지 —> 자식 가지(element) —> 잎

이러한 DOM 요소를 기반으로 브라우저가 해석하여 랜더링

텍스트 노드

  1. 생성하고자 하는 엘리먼트 요소를 생성 —> createElement()
  2. 원하는 텍스트를 변수에 저장 —> createTextNode()
  3. 해당 객체에 붙여준다 —> appendChild()
window.onload = () => {
  // p 엘리먼트 생성
  const eleNode = document.createElement("p");

  // 텍스트 노드 생성
  const txtNode = document.createTextNode("Welcome to DOM");

  // 합하기
  eleNode.appendChild(txtNode); // <p>Welcome to DOM</p>

  // body에 붙이기
  document.body.appendChild(eleNode);
};

이미지 노드

  1. 생성하고자 하는 엘리먼트 요소를 생성
  2. 생성한 img 엘리먼트에 성을 추가 ( . or setAttribute() )
  3. 해당 객체에 붙여준다 —> appendChild()
window.onload = () => {
  // img 엘리먼트 생성
  const imgNode = document.createElement("img");

  // 생성한 이미지 엘리먼트(태그)에 속성 추가
  imgNode.src =
    "https://cdn.pixabay.com/photo/2020/11/07/13/07/waves-5720916_960_720.jpg";
  imgNode.width = 400;
  imgNode.height = 300;

  //   body에 붙이기
  document.body.appendChild(imgNode);
};

setAttribute() 메서드를 이용하여 속성 추가

—> 사용자 정의 속성을 직접 만들어서 추가하는 것이 가능

window.onload = () => {
  // img 엘리먼트 생성
  const imgNode = document.createElement("img");

  //   생성한 이미지 엘리먼트에 속성을 추가
  imgNode.setAttribute(
    "src",
    "https://cdn.pixabay.com/photo/2020/11/07/13/07/waves-5720916_960_720.jpg"
  );
  imgNode.setAttribute("width", 400);
  imgNode.setAttribute("height", 400);
  imgNode.setAttribute("addProperty", "obj");

  //   <img src="https://cdn.pixabay.com/photo/2020/11/07/13/07/waves-5720916_960_720.jpg" width="400" height="400" addproperty="obj1">

  //   body에 붙이기
  document.body.appendChild(imgNode);
};

innerHTML vs innerText

window.onload = () => {
  // 문자열 변수 생성
  let strHtml = "";
  strHtml += "<h1>제목 : 동해안 파도</h1>";
  strHtml +=
    "<img src='https://cdn.pixabay.com/photo/2020/11/07/13/07/waves-5720916_960_720.jpg'";
  strHtml += "width='400' height='300'>";

  //   --> 텍스트 자체로 삽입
  document.body.innerText = strHtml;

  //   HTML 태그로 삽입
  document.body.innerHTML = strHtml;
};

사용자 입력 폼과 노드 추가

버튼 클릭시 사용자 이름과 홈페이지 주소가 바디에 추가

// index.html
<!DOCTYPE html>
<html lang="en">
  <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>
  </head>
  <body>
    <form>
      <label for="user_name">
        수강생 이름: <input type="text" size="50" id="user_name" /> <br />
      </label>
      <label for="user_home">
        수강생 홈피: <input type="text" size="50" id="user_home" /> <br /><br />
      </label>
      <input type="button" id="btn" value="사용자 추가하기" />
    </form>
    <br />
    <div id="memberList"></div>
    <script src="app.js"></script>
  </body>
</html>
// app.js
window.onload = () => {
  document.getElementById("btn").addEventListener("click", function () {
    const user_name = document.getElementById("user_name");
    const user_home = document.getElementById("user_home");

    // a 태그 노드 생성
    const aNode = document.createElement("a");
    aNode.href = user_home.value;

    // 텍스트 노드 생성
    const txtNode = document.createTextNode(user_name.value);
    aNode.appendChild(txtNode);

    // 붙이기
    const memberList = document.getElementById("memberList");
    const br = document.createElement("br");

    memberList.appendChild(aNode);
    memberList.appendChild(br);
    user_name.value = "";
    user_home.value = "";
  });
};

노드 삭제

  1. 부모 요소를 선택하여 자식 요소 삭제
window.onload = () => {
  document.getElementById("btn").addEventListener("click", function () {
    const memberList = document.getElementById("memberList");
    const p1 = document.getElementById("p1");
    memberList.removeChild(p1);
  });
};
  1. 자식 요소를 선택하여 부모 노드를 호출
window.onload = () => {
  document.getElementById("btn").addEventListener("click", function () {
    const p1 = document.getElementById("p1");
    p1.parentNode.removeChild(p1);
  });
};

li의 문자열로 해당 요소 삭제

function removeEleByText(text) {
  const li = document.querySelectorAll("li");

  // 삭제
  li.forEach((e) => {
    if (e.innerText == text) {
      e.parentNode.removeChild(e);
    }
  });
}

document.getElementById("btn").addEventListener("click", function () {
  removeEleByText("박진수");
});

자바스크립트에서 Element 배열을 다룰 시

  1. querySelectorAll >> 자바스크립트 API가 아닌, 브라우저에서 지원하는 API. NodeList 객체를 반환한다.
  2. NodeList 객체의 프로토타입 메서드 >> forEach 메서드를 이용하여 순회하면서 각 엘리먼트를 비교하여 조건 처리
  3. 모던 브라우저의 경우는 대부분 지원 (IE 지원 x)
💡 const li = [...document.querySelectorAll("li")]; console.log(li); // Array 객체를 반환 : (4) [li#1, li#2, li#3, li#4]

NodeList vs Array

  1. Length 속성을 가짐
  2. item() 메서드(NodeList)
console.log(li.item(0)); // 첫번째 li 요소
  1. 참조를 벗어날 때
console.log(li.item(4)) // NodeList >> null
console.log(li[4])      // Array >> undefined

예제

선택한 이미지 보여주기

// index.html
<!DOCTYPE html>
<html lang="en">
  <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>
    <link rel="stylesheet" href="main.css" />
  </head>
  <body>
    <div class="wrap">
      <ul>
        <li>
          <img src="01.jpg" alt="" class="smallImg" data-image="01.jpg" />
        </li>
        <li>
          <img src="02.jpg" alt="" class="smallImg" data-image="02.jpg" />
        </li>
        <li>
          <img src="03.jpg" alt="" class="smallImg" data-image="03.jpg" />
        </li>
        <li>
          <img src="04.jpg" alt="" class="smallImg" data-image="04.jpg" />
        </li>
      </ul>
      <div class="box">
        <img src="05.jpg" alt="" id="bigImg" data-image="05.jpg" />
      </div>
    </div>

    <script src="app.js"></script>
  </body>
</html>
// app.js
const imgs = document.querySelectorAll(".smallImg");

for (let i = 0; i < imgs.length; i++) {
  imgs[i].onclick = function () {
    const bigImg = document.getElementById("bigImg");
    bigImg.src = this.dataset.image;
  };
}

//-------------------------//

// forEach 사용
imgs.forEach((i) => {
  i.addEventListener("click", function () {
    document.getElementById("bigImg").src = this.dataset.image;
  });
});

onclick vs addEventListener

onclick

  • 하나의 콜백 함수(리스너)만 지정해서 등록 —> DOM 초기부터의 메서드
  • 재정의하면 기존의 이벤트 핸들러를 덮어씀
window.onload = () => {
  const e = document.getElementById("btn");
  e.onclick = () => {
    alert("1번"); // 실행안됨
  };
  e.onclick = () => {
    alert("2번"); // --> 실행
  };
};

addEventListener

  • 여러 개의 이벤트 리스너를 등록하여 처리 —> 덮어쓰지 않음
  • 3번째 파라미터 값으로 버블링, 캡처링 등의 사용여부를 설정할 수 있다. > 기본은 false
  • false > 버블링으로 동작 : 이벤트가 발생한 요소에서 window까지 이벤트를 전파(propagation)
  • true > 캡처링으로 동작 : 부모객체—> 자식객체
  • event.stopPropagation : 다음 캡처링이나 버블링을 멈춤
window.onload = () => {
  const e = document.getElementById("btn");
  e.addEventListener("click", function () {
    alert("1번");
  });
  e.addEventListener("click", function () {
    alert("2번");
  });
  // 순서대로 둘 다 실행
};

event.target vs event.currentTarget

window.onload = () => {
  const lis = document.querySelectorAll("li");
  lis.forEach((e) => {
    e.addEventListener("click", function (e) {
      console.log(e.target);
			// <img/> : 이벤트가 일어날 (자식) 객체
			// 이벤트 버블링의 가장 끝단에 위치한 마지막 요소를 반환

      console.log(e.currentTarget);
			// <li><img/></li> : 이벤트가 위임된 부모 객체를 반환
    });
  });
};
profile
즐거운 서비스를 추구합니다.

0개의 댓글