DOM에서 이벤트 처리하기

나혜수·2023년 2월 1일
0

자바스크립트 

목록 보기
9/14

웹 요소의 스타일 가져와서 수정하기

웹 요소의 스타일 속성에 접근할 때는 .style 예약어를 쓰고 CSS 속성을 적는다.
background-color, border-radius처럼 하이픈이 포함된 속성은 낙타 표기법으로 입력한다.
→ backgroundColor, borderRadius

document.querySelector("#heading").style.color = "white"
document.querySelector("#heading").style.backgroundColor = "gray"
document.querySelector("#heading").style.display = "block"

무엇을 화면에 표시하거나 감추려면 CSS 속성 중 display or visibility 속성을 사용한다.
display : none을 사용해 웹 요소를 화면에서 감추면 그 요소가 차지하던 공간도 사라지지만, visibility : hidden을 사용해 웹 요소를 감추면 요소가 있던 공간은 빈 상태로 남아 있게 된다.


Ex) 사각형 위로 마우스 포인터를 올리면 초록색 원으로 바뀌고, 포인터를 치우면 원래 도형을 되돌아감

var Rect = document.querySelector("#rect")
Rect.addEventListener("mouseover",function(){
  Rect.style.backgroundColor = "green"
  Rect.style.backgroundRadius = "5o%"
})
Rect.addEventListener("mouseout",function(){
  Rect.style.backgroundColor = ""    // Rect 요소의 배경색 지우기
  Rect.style.backgroundRadius = ""   // Rect 요소의 테두리 둥글게 처리 안 함 
})

Ex) display 속성을 사용해 상세 설명 링크 만들기

<div id = "desc">
  <ul> ... </ul>
  <a href = "#" id = "view">상세 설명 보기</a>
</div>

<div id = "detail">
  <h2>상품 상세 정보</h2>
</div>  
var isOpen = false // #detail 요소가 현재 화면에 표시된 상태인지 감춰진 상태인지를 저장할 변수 
var view = document.querySelector("#view")

view.addEventListener("click",function(){
  if(isOpen = false){
    document.querySelector("#detail").style.display = "block"
    View.innerText = "상세 설명 닫기"
    isOpen = true 
  }
  else{
    document.querySelector("#detail").style.display = "none"
    View.innerText = "상세 설명 보기"
    isOpen = false
  }
})

DOM에 요소 추가하기

새로운 노드 추가 방법을 살펴보기 전 DOM 트리에 어떤 노드가 있었는지 복습해보자.

  • 요소 노드 : 모든 HTML 태그
  • 텍스트 노드 : 태그에서 사용하는 텍스트 내용
  • 속성 노드 : 태그에 있는 속성
  • 주석 노드

웹 문서의 요소는 단순히 태그만 있는게 아니라 속성과 내용을 함께 사용한다. 따라서 <h1>,<p>태그를 추가하고 싶다면 요소 노드뿐 아니라 태그 안에 있는 텍스트와 속성도 노드로 추가해야 한다.


새로운 노드를 만들거나 부모 노드에 연결할 때는 다음 메소드를 사용한다.

  1. creatElement( ) : 새 요소를 만든다.

  2. creatTextNode( ) : 텍스트 내용이 있을 경우 텍스트 노드를 만든다.
    appendChild( ) : 텍스트 노드를 요소 노드의 자식으로 추가한다.

    방법1 : createAttribute( )setAttributeNode( )
    or
    방법2 : setAttribute( )

  3. appendChild( ) : 새 요소 노드를 부모 노드에 추가한다.
var newP = document.creatElement("p")
var newText = document.creatTextNode("주문이 완료되었습니다.")
newP.appendChild(newText)
document.body.appendchild(newP)

// 방법1
var attr = document.creatAttribute("class")
attr.value = "accent"
newP.setAttributeNode(attr) 

// 방법2 이게 더 간단하다!
newP.setAttribute("class","accent")

EX) 참가 신청 명단 프로그램 만들기
이름을 입력하고 신청 버튼을 누르면 그 정보는 서버로 넘겨져 DB에 저장된다. 서버에 저장되는 것과 동시에 웹 브라우저 화면에 신청 명단을 표시한다.

<body>
  <div id = "container">
    <h1>참가 신청</h1>
    <form action = "">
      <input type = "text" id = "userName" placeholder = "이름" required>
      <button onclick = "newRegister();return false">신청</buttton>
      <!-- button 태그에 return false를 추가하지 않으면 버튼을 눌렀을 때 빈 페이지로 넘어간다. -->
    </form>
    <hr>
    <div id = "nameList"></div>
  </div>
</body>  
function newRegister(){
  var newP = document.createElement("p")
  var userName = document.querySelector("#userName") // 텍스트 필드 내용 가져오기 
  var newText = document.creatTextNode(userName.value)
  newP.appendChild(newText)
  
  var nameList = document.quertSelector("#namelist")
  nameList.appendChild(newP)
  userName.value = "" // 다시 이름 입력할 수 있게 텍스트 필드 비우기 
}
  

추가한 노드 순서 바꾸기 or 삭제하기

추가한 노드의 순서를 바꾸거나 삭제하기 위해서는 DOM에서 노드를 다루기 위한 몇 가지 함수를 더 사용해야 한다.

querySelectorAll

<div id = "container">
  <h1>참석자 명단</h1>
   <div id = "nameList">
     <p>홍길동 <span class = "del"> X </span></p>
     <p>유현준 <span class = "del"> X </span></p>
     <p>이상협 <span class = "del"> X </span></p>
  </div>
</div>

querySelectorAll을 사용해서 여러 개의 노드를 한 번에 가져오면 3개의 p노드가 한꺼번에 저장되는데 이를 노드 리스트라고 한다. 인덱스와 함께 값이 저장되고 length 속성을 사용할 수 있는 유사 배열 형태이다.
노드 리스트의 특정 위치에 접근할 때는 인덱스를 사용하면 된다.

document.querySelectorAll("p") // NodeList(3) [p,p,p]
document.querySelectorAll("p")[0] //<p> ... </p>

hasChildNodes, childNodes, childeren

hasChildNodes는 특정 노드에 자식 노드가 있는지 확인하는 함수이다. 자식 노드가 있다면 true, 없다면 false를 반환한다.

자식 노드가 있다면 childNodes 속성을 사용해 현재 노드의 자식 노드에 접근할 수 있다.
이때 요소 노드뿐만 아니라 태그와 태그 사이 줄바꿈도 빈 텍스트 노드인 자식 노드로 인식한다.
또한 주석 노드까지 접근할 수 있다. 밑의 예제에서는 <div> 태그 다음 줄바꿈, <P> 태그 사이 줄바꿈, </div> 앞에 줄바꿈을 빈 텍스트 노드로 인식하였다.

만약 요소 노드에만 접근한다면 children 속성을 사용하면 된다.

document.querySelectorAll("p")[0].hasChildNodes() // false 

document.querySelector("#nameList").childNodes() 
// NodeList(7) [text,p,text,p,text,p,text]

document.querySelector("#nameList").children() 
//HTML Collection(3) [p,p,p] 

insertBefore, removeChild, parentNode

자식 노드를 추가하는 appendChild 함수는 부모 노드에 자식 노드가 있을 경우 마지막 자식 노드로 추가된다. 하지만 insertBefore 함수를 사용하면 기준이 되는 노드를 정하고 그 앞에 자식 노드를 추가할 수 있다. 첫번째 인수는 추가하는 노드, 두번째 인수는 기준이 되는 노드이다.

var nameList = document.querySelector("#nameList") 
namelist.insertBefore(nameList[2],nameList[0])

removeNode는 부모 노드에서 자식 노드를 삭제하는 함수로 인수에는 자식 노드가 들어간다.
노드는 스스로 자신을 삭제할 수 없기 때문에 부모 노드에 접근 후 부모 노드에서 삭제해야 한다. 따라서 특정 노드를 삭제하기 위해선 그 노드의 부모 노드를 찾아야 한다. 부모 노드 정보를 가지고 있는 속성은 parentNode 로 현재 노드의 부모 요소를 반환한다.

var var firstDel = document.querySelectorAll(".del")[0] 
var fistP = document.querySelectorAll("p")[0] 
firstP.removeChild(firstDel) // 삭제된 노드 반환 <span class = "del"> X </span>

EX) 최근 입력한 이름이 명단 맨 위에 표시되고 삭제 기능이 추가된 참가 신청 명단 프로그램

function newRegister(){
  var newP = document.createElement("p")
  var userName = document.querySelector("#userName") // 텍스트 필드 내용 가져오기 
  var newText = document.creatTextNode(userName.value)
  newP.appendChild(newText)
  
  var delBttn = document.createElement("span")  
  var delText = document.creatTextNode("X")
  delBttn.setAttribute("class","del")
  delBttn.appendChild(delText)
  newP.appendChild(delBttn) 
  
  var nameList = document.quertSelector("#namelist")
  nameList.insertBefore(newP,nameList.children[0])
  userName.value = "" // 다시 이름 입력할 수 있게 텍스트 필드 비우기 
  
  var removeBttns = document.quertSelectorAll(".del")
  for (var i = 0; i < removeBttns.length; i++){
    removeBttns[i].addEventListener("click", function(){
      if (this.parentNode.parentNode){
        this.parentNode.parentNode.removeChild(this.parentNode)}
    })
  } 
}

이벤트리스너 안에서의 thise.currentTarget과 같다. e.currentTarget은 지금 이벤트가 동작하는 곳을 뜻한다. (즉, addEventListener 부착된 DOM 요소)
만약 이벤트리스너 안에서 콜백 함수를 쓴다면 콜백 함수의 thiswindow를 가리킨다.

profile
오늘도 신나개 🐶

0개의 댓글