상세 컨텐츠

본문 제목

[자바스크립트] DOM, 이벤트

자바스크립트

by front-hyun 2023. 4. 13. 18:46

본문

내부에서 스크립트 사용

<script> 태그는 HTML문서 내부에서 자바스크립트를 사용할 수 있게 해줍니다.
내부에서 스크립트를 사용하는 방식은 스크립트의 사용량이 간단할 때 사용합니다.
스크립트량이 많아지면, 외부에 스크립트파일을 만들어서 불러오기 형식으로 쓰는게 좋습니다.

<!DOCTYPE html>
<html>

<head>
</head>

<body>
    <h1> HTML 내부에서 자바스크립트 실행 </h1>

    <script>	// HTML 문서에서 JS 사용
        alert("안녕하세요. 알람 입니다.")	// JS 함수
    </script>
</body>
</html>

 

외부 스크립트 사용

자바스크립트를 사용하는 언어를 따로 파일로 생성해서 저장할 수 있습니다.
따로 저장한 파일을 src 속성을 통해 HTML 문서 내부에 불러와서 사용할 수 있습니다.

<script src="절대경로 / 상대경로 / URL"></script>

<script src="/local/project/script.js"></script>

 

DOM

  • Document Object Model(문서 객체 모델)
  • HTML 페이지에 태그를 추가, 수정, 제거할 수 있습니다.
  • 넓은 의미로 웹 브라우저가 HTML 페이지를 인식하는 방법, 좁은 의미로는 document 객체와 관련된 객체의 집합입니다.
  • 웹 브라우저에 HTML 파일을 끌어다 놓으면 웹 브라우저는 HTML 파일을 분석해 화면에 출력합니다. 이때 웹 브라우저가 HTML 파일을 분석하고 출력하는 방식이 DOM입니다.

문서 객체란?

-HTML 태그를 자바스크립트에서 사용할 수 있는 객체로 만든 것입니다.

-문서 객체를 조작한다는 말은 태그를 조작한다는 말과 같습니다.

-문서 객체를 조작하면 태그 내부의 글자, 스타일, 속성을 변경할 수 있습니다.

 

DOM TREE

  • 각 요소를 노드라고 하며, 요소 노드와 텍스트 노드로 구분합니다.
  • h1 태그와 script 태그처럼 요소를 생성하는 노드를 요소 노드라고 합니다.
  • 화면에 출력되는 문자열인 "My header", "My title" 등은 텍스트 노드라고 합니다.

 

 

주요 노드 타입

 

노드 선택하기

 

모든 노드 탐색

parentNode 부모 노드 반환
childNodes 모든 자식 노드 반환
firstChild 첫 번째 자식 노드 반환
lastChild 마지막 자식 노드 반환
previousSibling 이전 형제 노드 반환
nextSibling 다음 형제 노드 반환

 

요소 노드 탐색

parentElement 부모 요소 노드 반환
children 자식 요소 노드 반환
firstElementChild 첫 번째 자식 요소 노드 반환
lastElementChild 마지막 자식 요소 노드 반환
previousElementSibling 이전 요소  노드 반환
nextElementSibling 다음 요소 노드 노드 반환

 

 

메서드로 노드 선택하기

  • 속성값과 태그명 사용하기 - get 메서드
getElementById(<id 속성값>) id 속성값과 일치하는 요소 노드를 1개만 선택합니다.
getElementsByClassName(<class 속성값>) class 속성값과 일치하는 요소 노드를 모두 선택합니다.
getElementsByTagName(<태그명>) 태그명과 일치하는 요소 노드를 모두 선택합니다.
  • CSS 선택자 사용하기 - query 메서드

-script 태그는 <body>의 가장 마지막에 위치해야 합니다.

querySelector(<CSS 선택자>) 매개변수로 넘어오는 CSS 선택자에 해당하는 노드를 1개만 선택합니다.
매개변수로 전달한 CSS 선택자로 선택되는 "첫 번째 태그"만 선택합니다.
querySelectorAll(<CSS 선택자>) 매개변수로 넘어오는 CSS 선택자에 해당하는 노드를 모두 선택합니다.

 

<body>
    <h1> h1 태그 </h1>
    <h2> h2 태그 </h2>

    <script>
    //h1 태그의 배경 색상 변경
       document.querySelector('h1').style.backgroundColor="red";
    //h2 태그의 글자 색상 변경
       document.querySelector('h2').style.color="red";
    </script>
</body>

노드 조작하기 - 콘텐츠 조작하기

textContent 요소 노드의 모든 텍스트에 접근합니다.
innerText 요소 노드의 텍스트 중 웹 브라우저에 표시되는 텍스트에만 접근합니다. 
innerHTML 요소 노드의 텍스트 중 HTML 태그를 포함한 텍스트에만 접근합니다. 문서 객체 내부의 글자를 나타냅니다

 

  • 조작시 접근한 노드의 콘텐츠를 가져올 뿐아니라 속성에 값 할당 시 각 노드의 콘텐츠를 바꿀수 있습니다.
<body>
    <h1 id="header"> header 1 </h1>

    <script>
       const header=document.getElementById('header');
       const originText=header.innerHTML;
       header.innerHTML="자바스크립트로 변경<br>";
      header.innerHTML+="원래는"+originText;

      console.log(header.innerHTML);
    </script>
</body>

 

노드 조작하기 - 스타일 조작하기

<노드>.style.<css 속성명> = <속성값>;
<p id="text">text</p>
<script>
	const pE1 = document.querySelector("p"); // 노드 선택하기
    pE1.style.color = "red";
</script>

 

 

 

노드 조작하기 - 클래스 속성 조작하기

//추가
<노드>.classList.add("class속성값");
//삭제
<노드>.classList.remove("class속성값");
//추가와 삭제 반복
<노드>.classList.toggle("class속성값");

 

setInterval() 함수

 

  • 웹페이지의 특정 부분을 주기적으로 업데이트해줘야 하거나, 어떤 API로 부터 변경된 데이터를 주기적으로 받아와야 할 때 자바스크립트의 setInterval() 함수를 사용합니다.
  • setInterval() 함수는 어떤 코드를 일정한 시간 간격을 두고 반복해서 실행하고 싶을 때 사용합니다.
  • 함수 API는 setTimeout() 함수와 대동소이한데요. 첫번째 인자로 실행할 코드를 담고 있는 함수를 받고, 두번째 인자로 반복 주기를 밀리초(ms) 단위로 받습니다.
  <div onclick="alert('클릭했습니다1.')">클릭</div>
  <div onclick="view()">클릭</div>
    
  <script>
    function view() {
      alert("클릭했습니다2.");
    }
  </script>
<!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>
    <style>
        /* 스타일로 텍스트의 색상과 위치 변경 */
   
        .red-color {
            color: red;
        }
        .fz20 {
            font-size: 20px;
        }
    </style>
</head>
<body>
    <p id="text"> text </p>

    <script>
        function change(){
            const pEl=document.querySelector("#text");
            pEl.classList.toggle("red-color");
            pEl.classList.toggle("fz20");
        }
       setInterval(change,1000);
    </script>
</body>
</html>

[실습 3]  

이벤트

  • 마우스 이벤트, 키보드 이벤트, 포커스 이벤트, 폼 이벤트가 있습니다.
  • 웹페이지에서 마우스를 클릭했을 때, 키를 입력했을 때, 특정요소에 포커스가 이동되었을 때 어떤 사건을 발생시키는 것입니다.

 

이벤트 등록

1. 인라인 방식

  • 인라인 이벤트 모델은 HTML 태그 내부에서 이벤트를 연결하는 방법입니다.
  • 웹 페이지의 가장 기본적인 이벤트 연결 방식으로 HTML 태그 내부에 자바스크립트 코드를 넣어 이벤트를 실행합니다.
<태그명 on이벤트 = 자바스크립트 코드> </태그명>
  //1번째 예시
  <div onclick="alert('클릭했습니다1.')">클릭</div>
  <div onclick="view()">클릭</div>
    
  <script>
    function view() {
      alert("클릭했습니다2.");
    }
  </script>
  
  
  //2번째 예시
  <button onClick="clickEvent()"> 클릭 </button>

   <script>
    function clickEvent(){
        alert("click");
    }
   </script>

 

2. 프로퍼티 리스너

  • 프로퍼티 리스너 방식은 이벤트 대상에 해당하는 객체의 프로퍼티로 이벤트를 등록하는 방식입니다.
  • 인라인 방식에 비해서 HTML과 JavaScript를 분리할 수 있다는 점에서 선호되는 방식이지만 뒤에서 배울 addEventListener 방식을 추천합니다.
<body>
     <button> 클릭 </button>

    <script>
     const btnEl=document.querySelector("button");
     btnEl.onclick=function(){
         alert("click");
     }
    </script>
    </body>

 

 

3. 이벤트 등록 메서드

 

<노드>.addEventListener("<이벤트 타입>", <이벤트 함수>);
<body>
     <button> 클릭 </button>

    <script>
     const btnEl=document.querySelector("button");
     btnEl.addEventListener("click", ()=>{alert("button Click");});
    </script>
    </body>

 

[실습 4]  버튼 클릭 시, "아기사자 파이팅"이 사라지도록 코드를 작성하세요.

<!DOCTYPE HTML>
<html>

<head>
  <meta charset="utf-8">
</head>

<body>

  <input type="button" id="hider" value="Text를 숨기려면 클릭하세요." />
  <div id="cheerup">아기사자 파이팅</div>

  <script>
  const btnEl=document.getElementById("hider");
     btnEl.addEventListener("click", 
                  ()=>{document.getElementById("cheerup").style.display="none";});
  </script>

</body>
</html>

[실습 5]  사용자가 입력한 숫자에 해당하는 단어를 출력하는 프로그램을 작성하세요.

<!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>
	<h1>Number to Word Converter</h1>
	<input type="text" id="numberInput" placeholder="숫자를 입력하세요.">
	<button id="convertButton">변환</button>
	<p id="output"></p>
	<script src="script.js"></script>
</body>
</html>
// numberInput, convertButton, output 요소를 가져옵니다.
const convertButton = document.getElementById("convertButton"); // 변환 버튼
const output = document.getElementById('output'); // 출력될 문자열
const numberInput = document.getElementById('numberInput'); // 입력될 숫자

// output 문자열 출력해줄 함수 정의
function outputText(sub) {
    if (sub == 1) output.textContent = "하나";
    else if (sub == 2) output.textContent = "둘";
    else if (sub == 3) output.textContent = "셋";
    else output.textContent = "해당하는 숫자에 대한 단어가 없습니다.";
}

// convertButton에 click 이벤트에 대한 이벤트 핸들러를 등록합니다.
convertButton.addEventListener("click", () => {
    let subText = numberInput.value; // numberInput에서 입력한 값을 가져옵니다.
    outputText(subText); // number에 해당하는 단어를 출력합니다.
});

// numberInput에 keydown 이벤트에 대한 이벤트 핸들러를 등록합니다.
numberInput.addEventListener("keydown", (event) => {
    if (event.key === "Enter") {
        let subText = numberInput.value; // 눌린 키의 코드를 가져옵니다.
        outputText(subText); // 엔터 키를 눌렀을 때 convertButton을 클릭한 것과 같은 효과를 냅니다.
    }
});

노드 추가/삭제

노드 생성(노드 추가)

 

<!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>
     

<div id="homzzang">

    <p id="p1">hyuna</p>

    <p id="p2">tistory</p>

</div>



<script>

var p = document.createElement("p"); // P요소(=노드) 생성

var intro = document.createTextNode("홈페이지 제작관리"); // P요소에 넣은 내용 (= 텍스트노드 생성)

p.appendChild(intro); // P요소에 내용 넣기

var hz = document.getElementById("homzzang"); // 부모요소

hz.appendChild(p); // 부모요소에 생성한 P 요소 추가

</script>
</body>
</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>
    <div id="homzzang">
        <p id="p1">hyuna</p>
        <p id="p2">tistory</p>
    </div>
    <script>
    
    var hz = document.getElementById("homzzang"); // 부모요소
    var p1 = document.getElementById("p1"); // 자식요소 (= 삭제할 요소)
    
    hz.removeChild(p1); // 부모요소에서 자식요소 제거
    
    </script>
   
</body>
</html>

이벤트와  this

  • 결과적으로 this는 어떤 내부에서 쓰였는지가 가장 중요합니다.
  • 일반 함수 안에서는 window를, 생성자 함수로 만든 객체의 메소드에서는 자기 자신의 객체를, 이벤트리스너 안에서 사용된 this는 e.currentTarget을 나타냅니다. (이벤트리스너에서 따로 만든 함수는 일반 함수로 분류)

폼 태그 다루기-체크박스, 라디오버튼, 콤보박스

체크 박스 가져오기

<!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>
    <h3>멋쟁이사자처럼 11기</h3>
   <input type="checkbox" id="front" name="role" value="프론트엔드"> 프론트엔드
    <input type="checkbox" id="backend" name="role" value="백엔드"> 백엔드
    <input type="checkbox" id="planning" name="role" value="기획"> 기획
    <input type="checkbox" id="operation" name="role" value="운영"> 운영
    <input type="checkbox" id="education" name="role" value="교육"> 교육
<button onclick="getCheckedValues()">선택된 값 가져오기</button>

<script>
    function getCheckedValues(){
        let checkboxes=document.querySelectorAll('input[type="checkbox"]');
        let checkValues=[];

        checkboxes.forEach(checkbox =>{
            if(checkbox.checked){
            checkValues.push(checkbox.value);}
        });

        console.log('체크된 값: ', checkValues);
    }
</script>
</body>
</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>
    <h3>멋쟁이사자처럼 11기</h3>
    <input type="radio" id="front" name="role" value="프론트엔드"> 프론트엔드
    <input type="radio" id="backend" name="role" value="백엔드"> 백엔드
    <input type="radio" id="planning" name="role" value="기획"> 기획
    <input type="radio" id="operation" name="role" value="운영"> 운영
    <input type="radio" id="education" name="role" value="교육"> 교육
<button onclick="getCheckedValues()">선택된 값 가져오기</button>

<script>
    function getCheckedValues(){
        let radioButtons
        =document.querySelectorAll('input[type="radio"]');
        let checkValue;

        radioButtons.forEach(radioButton =>{
            if(radioButton.checked){
                checkValue=radioButton.value;}
        });

        console.log('체크된 값: ', checkValue);
    }
</script>
</body>
</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>
    <select name="language" onchange="handleOnChange(this)">
        <option value="korean">한국어</option>
        <option value="english">영어</option>
        <option value="chinese">중국어</option>
        <option value="spanish">스페인어</option>
      </select>
      <div id='result'></div>

<script>
   function handleOnChange(e) {
  // 선택된 데이터 가져오기
  const value = e.value;
  
  // 데이터 출력
  document.getElementById('result').innerText
    = value;
}
</script>
</body>
</html>

관련글 더보기