Implicit Object
DOM Node
• document 는 브라우저에서 실행되는 프런트 웹 애플리케이션에서 이용할 수 있는 내장 객체로 브라우저에 출력 되는 HTML 문서 자체를 지칭하는 객체
• document 에 HTML 문서가 파싱되어 만들어진 다양한 DOM 노드 객체가 만들어지며 코드에서는document 객체를 이용해 이 노드에 접근해 다양한 작업을 한다.
- 요소 노드 : 태그를 지칭하는 노드
- 속성 노드 : 태그의 속성을 지칭하는 노드
- 텍스트 노드 : 태그의 바디에 작성된 글을 지칭하는 노드
- 주석 노드 : 문서의 주석을 지칭하는 노드
Node Selector
▼ getElementById()
• HTML 문서의 태그를 지칭하는 DOM 노드를 선택하여 그 노드에 있는 값을 획득하거나 그 노드에 값을 출력한다.
• 자바스크립트에서 원하는 노드를 선택하는 기능이 있어야 하는데 이 부분을 노드 선택자(Selector) 라고한다.
• id 속성값으로 식별해 획득을 하거나 노드에 추가된 CSS 클래스 명으로 식별하거나 아니면 태그명으로 식별해 획득해야 한다. (노드를 획득하는 방법은 여러가지가 있지만 가장 기본이 되는 방법이 id 값을 이용해 획득하는 것)
▼ getElementsByClassName()
• 태그와 상관없이 CSS 에 의해 동일한 화면 효과가 적용된 노드를 획득하는 경우인데 이를 위해getElementsByClassName() 이라는 함수를 제공하며 getElementsByClassName() 함수의 매개변수에 CSS 클래스명을 지정하면 이 클래스명이 선언된 모든 노드객체가 HTMLCollection 타입으로 반환한다.
▼ getElementsByName()
• 태그에 name 속성을 설정하고 그 name 속성값으로 노드를 획득하기 위한 함수가 getElementsByName()이며
이 함수의 매개변수에 name 속성값을 지정하면 반환 값은 HTMLCollection 이다.
▼ querySelector() 와 querySelectorAll()
• querySelector(), querySelectorAll() 함수는 document 객체 혹은 element 객체의 함수이다.
document 는 HTML 문서 자체를 지칭하며 document.querySelector() 를 사용하면 전체 HTML 문서내에서원하는 노드를 획득하겠다는 것이고 element 는 HTML 문서내의 특정 노드를 지칭하는 객체이며 element.querySelector() 를 이용하면 특정 노드 하위에 있는 노드들 중 조건에 맞는 노드를 획득한다.
- querySelector() : 조건에 맞는 첫 노드를 반환
- querySelectorAll() : 조건에 맞는 모든 노드를 배열로 반환
- CSS Selector 로 조건 설정
<body>
<div>one</div>
<div>two</div>
<div id="a1">three</div>
<div class="b1">four</div>
<div id="a2">
<div>five</div>
<div class="b1">six</div>
</div>
<div>
<input name="address" /><br />
<p id="result"></p>
</div>
<p><button onclick="idTest()">id test</button></p>
<script>
function idTest() {
//id 속성 값으로 노드 획득
let selectNode = document.getElementById('a1')
selectNode.style.backgroundColor = 'red'
}
</script>
<p><button onclick="tagNameTest()">tag name test</button></p>
<script>
function tagNameTest() {
//tag name 으로 노드 획득
//getElementsByTagName - 걸리는 노드 모두 반환
//HTMLCollection
let selectNode = document.getElementsByTagName('div')
for (let i = 0; i < selectNode.length; i++) {
selectNode[i].style.backgroundColor = 'red'
}
}
</script>
<p><button onclick="classTest()">class test</button></p>
<script>
function classTest() {
let selectNode = document.getElementsByClassName('b1')
for (let i = 0; i < selectNode.length; i++) {
selectNode[i].style.backgroundColor = 'red'
}
}
</script>
<p><button onclick="nameTest()">name test</button></p>
<script>
function nameTest(){
//name 으로 노드 획득, 그곳에 유저가 입력한 데이터 추출
//result 에 출력
let addressNode = document.getElementsByName('address')
let resultNode = document.getElementById('result')
resultNode.innerHTML = `${addressNode[0].tagName}, ${addressNode[0].value}`
}
</script>
<p><button onclick="selectorTest()">query select test</button></p>
<script>
function selectorTest(){
let selectNode = document.querySelectorAll('#a2 div')
for (let i = 0; i < selectNode.length; i++) {
selectNode[i].style.backgroundColor = 'red'
}
}
</script>
</body>
Node 이용
▼ innerHTML vs innerText
• 노드 객체를 다양하게 이용해 주어야 하는데 가장 대표적인 것이 노드 객체 하위에 선언된 자식 노드를 얻거나 변경하는 것이며 어떤 노드의 자식 노드를 이용할 때 innerHTML 과 innerText 를 이용할 수 있는데 이 둘은 차이가 있다
innerHTML 은 어떤 노드의 하위에 선언된 모든 구성요소를 포함시키지만
innerText 는 테스트 노드만 포함시키기 때문에 차이가 발생하게 된다.
• innerHTML, innerText 에 값을 대입해 어떤 노드의 하위 부분을 동적으로 변경시킬 수 있다.
▼ 속성 이용
• 노드의 속성 값을 획득하거나 변경해야 하는 경우가 있습니다. 그리고 경우에 따라 노드의 속성을 제거해야하는 경우가 있는데 이를 위해 아래의 함수를 제공한다.
- getAttribute() : 노드의 속성 값 획득
- setAttribute(): 노드의 속성 값 변경
- removeAttribute() : 노드의 속성 삭제
- hasAttribute() : 노드에 속성이 있는지 판단
▼ 타겟팅과 버블링
• 중첩구조에서 여러 노드에 이벤트 핸들러를 등록하게 되는 경우가 있다.
• 노드는 트리구조로 구성되고 트리구조의 여러 노드에 이벤트 핸들러가 등록될 수 있습니다. 이때 실행순서를 신경써야 하거나 혹은 이벤트 실행을 취소 시켜야 하는 경우가 있다
• 캡처링은 이벤트가 발생했을 때 상위 노드부터 하위노드로 이벤트가 전파되는 단계있고
반대로 버블링은 이벤트가 발생한 노드부터 상위 노드로 이벤트가 전파되는 단계이다.
• 하나의 이벤트가 발생하게 되면 캡처링과 버블링 단계를 거치면서 여러 노드에 등록된 이벤트 핸들러가 실행되게 되는데 이때 캡처링 단계에서 실행될 것인지 버블링 단계에서 실행된 것인지를 제어할 수 있다.
• 이벤트 처리를 캡처링 단계에서 할것인지 버블링 단계에서 할것인지 제어는 이벤트를 등록시키는 함수인addEventListener() 함수의 매개변수로 제어할 수 있다.
• addEventListener() 함수의 3번째 매개변수는 true/false 값을 가지는데 이 값이 false 이면 버블링 단계에서이벤트가 처리됨을 의미하며 true 이명 캡처링 단계에서 이벤트가 처리됨을 의미한다. (기본값이 false)
<body>
<div id="one">hello</div>
<div id="two"><a href="#">google</a></div>
<div id="result1"></div>
<div id="result2"></div>
<a id="link1" href="http://www.google.com">google</a>
<br/>
<a id="link2">link</a>
<br/>
<a id="link3" href="http://www.google.com">link</a>
<script src="main.js"></script>
</body>
"use strict";
//innerHTML vs innerText
//둘다 특정 노드의 바디를 지칭하는데 차이가 있다
//특정 노드에 바디를 획득하고자 한다
let oneNode = document.getElementById('one')
console.log(oneNode.innerHTML)//hello
console.log(oneNode.innerText)//hello
let twoNode = document.getElementById('two')
console.log(twoNode.innerHTML)//<a href="#">google</a>
console.log(twoNode.innerText)//google
//특정 노드의 바디에 문자열을 추가해서 출력하고자 할 때
let result1 = document.getElementById('result1')
let result2 = document.getElementById('result2')
//동적 문자열이지만 innerHTML 로 지정한 문자열을 html parser가 파싱을 한다.
//태그가 포함되어 있다면 태그 효과를 적용한다
result1.innerHTML = '<a href="#">google</a>'
//동적 문자열 내에 태그가 있다고 하더라도 태그로 인지하지 않고 화면에 출력해야할
//문자열로 인지, 태그가 화면에 출력
result2.innerText = '<a href="#">google</a>'
//속성 핸들링
let link1 = document.getElementById('link1')
//속성 값 획득
console.log(link1.href)//http://www.google.com/
console.log(link1.getAttribute('href'))//http://www.google.com
//속성 변경
let link2 = document.getElementById('link2')
// link2.href = 'http://www.naver.com'//ok
link2.setAttribute('href', 'http://www.naver.com')
//속성 제거
let link3 = document.getElementById('link3')
link3.removeAttribute('href')
console.log(link3.hasAttribute('href'))//false
▼ preventDefault()
• 이벤트를 중단시키는 방법은 preventDefault() 함수를 이용하는 방법과 stopPropagation() 함수를 이용하는방법으로 나누어 지는데 preventDefault() 는 노드에 기본으로 등록된 이벤트가 처리되지 않게 하기 위해서 사용된다.
▼ stopPropagation()
• 노드에 발생하는 이벤트는 캡처링과 버블링 단계를 거쳐 여러 이벤트 핸들러가 실행될 수 있으며
stopPropagation() 은 이 캡처링과 버블링을 중단시키는 함수다.
▼ 스타일 이용
• 자바스크립트에서 노드에 적용된 스타일 값을 획득하거나 변경해야 하는 경우가 있는데,
이때 이용되는 것이 노드의 style 프로퍼티이다.
• 노드의 style 프로퍼티로 노드에 적용된 스타일을 이용할 때 스타일 명은 CSS 와 차이가 있다.
CSS 는 대소문자를 구분하지 않고 두 단어가 연결되어 스타일 이름이 지정되는 경우
– 로 두 단어를 연결하는 snake case 명명규칙을 따른다.
하지만 자바스크립트는 대소문자를 구분하며 두 단어가 연결되는 경우
뒷 단어의 첫 글자를 대문자로 하는 camel case 명명 규칙을 따른다.
CSS 에서 border-color, font-size 등 두 단어가 – 으로 연결된 것은
모두 자바스크립트에서는 borderColor, fontSize 등으로 이용해야 한다.
▼ 스타일 이용 - getComputedStyle() 함수로 스타일 값 획득
• style 프로퍼티는 태그내에서 style 속성으로 지정한 스타일만 이용할 수 있다.
외부에서 정의해서 적용된 스타일을 획득하고자 한다면 노드의 style 속성을 이용할 수 없으며
getComputedStyle() 함수를 이용해 주어야 한다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#area2 {
width: 200px;
height: 200px;
background-color: red;
}
.my-style {
width: 200px;
height: 200px;
background-color: blue;
}
</style>
</head>
<body>
<div id="area1" style="width: 200px; height: 200px; background-color: green;"></div>
<div id="area2"></div>
<div id="area3" class="my-style"></div>
<script src="main.js"></script>
</body>
</html>
"use strict";
let area1 = document.getElementById('area1')
let area2 = document.getElementById('area2')
let area3 = document.getElementById('area3')
//아래의 코드는 node.style, 즉 dom node tree 에서 획득한 것이다.
//node tree 에 유지되는 css 정보는 inline style 만.
console.log(area1.style.width)//200
console.log(area2.style.width)//
console.log(area3.style.width)//
//css 속성명 => camel case 로 이용해야 한다.
console.log(area1.style.height)//200
console.log(area1.style.backgroundColor)//green
//node 의 css 속성 값 변경.
area1.addEventListener('click', function(){
area1.style.backgroundColor = 'yellow'
area1.style.borderRadius = '50%'
})
//inline style 이 아닌 외부에 선언되어 적용된 css 값 획득
//style 태그 혹은 외부 css 파일
console.log(getComputedStyle(area1).width)//200
console.log(getComputedStyle(area2).width)//200
console.log(getComputedStyle(area3).width)//200
Node 추가
• 자바스크립트에서 HTML 문서에 새로운 노드를 추가하는 방법은 이미 살펴본 innerHTML 을 이용할 수 있다.
innerHTML 방식은 자바스크립트 코드에서 문자열을 추가한 것이고
추가된 문자열을 브라우저에서 노드로만드는 방식이지만 복잡한 구조의 노드를 추가하거나 추가하는 노드의 속성, 바디 문자열을 동적으로 변경하면서 추가하기에는 불편하다.
또한 document 객체에는 자바스크립트 코드에서 노드 객체를 직접 만들고 추가할 수 있는 함수를 제공한다.
▼ 노드 객체 생성
- createElement() : 요소 노드 생성
- createAttribute() : 속성 노드 생성
- createTextNode() : 텍스트 노드 생성
▼ appendChild() 로 노드 객체 추가
• 노드 객체는 노드 트리로 구성됨으로 어떤 노드를 다른 노드에 추가해서 화면을 구성하는데 이때 사용되는 함수가 appendChild() 이다. 또한 만들어진 노드 객체를 추가 해 준다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="result1"></div>
<div id="result2"></div>
<script src="main.js"></script>
</body>
</html>
"use strict";
let result1 = document.getElementById('result1')
result1.innerHTML = '<div><a href="#">link</a>hello</div>'
//위와 동일하게 node 를 create 해서 추가
let newDiv = document.createElement('div')
let newA = document.createElement('a')
let newHref = document.createAttribute('href')
newHref.value = '#'
let newAText = document.createTextNode('link')
let newDivText = document.createTextNode('hello')
newA.setAttributeNode(newHref)
newA.appendChild(newAText)
newDiv.appendChild(newA)
newDiv.appendChild(newDivText)
let result2 = document.getElementById('result2')
result2.appendChild(newDiv)
▼ insertBefore() 함수로 노드 추가
▼ 노드 객체 삭제
• 특정 노드를 삭제하고 싶다면 removeChild() 함수를 이용한다.
removeChild() 는 부모 노드에서 자식 노드를 삭제하기 위한 함수로
매개변수에 삭제하고자 하는 노드를 지정해 준다.
'BootCamp Review' 카테고리의 다른 글
2024.09.24 (Day 13) - JavaScript OOP / 생성자 함수 (0) | 2024.09.24 |
---|---|
2024.09.23 (Day 12) - JavaScript OOP / Object Literal (0) | 2024.09.24 |
2024.09.19-20 (Day 10,11) - JavaScript Implicit Object 2 (0) | 2024.09.20 |
2024.09.13-19 (Day 9,10) - JavaScript Implicit Object 1 (0) | 2024.09.19 |
2024.09.12 (Day 8) - JavaScript Event Programming (0) | 2024.09.12 |