everyday com-eat
작성일
2022. 1. 8. 18:15
작성자
갱수터
728x90

- DOM(Documnet Object Model) 문서 객체

- document API를 활용, html 요소를 검색하여 이벤트 등록 및 문서 제어가 가능하다.

API(Application Programming Interface) - 응용 프로그램 프로그래밍 인터페이스
Interface - 프로그램과 프로그램 혹은 사용자와 프로그램과 의사소통을 하기위한 구조(툴) <->JAVA와 다름

API - 메서드,속성
라이브러리 - 완성된 프로그램 > 외부에서 메서드,속성(API) 호출
프레임워크 - 프로그래밍을 쉽게 할 수 있게 구조(라이브러리) 제공 > 직접 코드 작성

 

id 검색

- html 요소 중 id 속성의 값을 가진 대상을 검색
- 찾고자 하는 id값과 일치하는 대상을 찾을 수 있다.
- api : documnet.getElemnetById('찾을id');
- 특징 : 동일한 id값이 여러개 있더라도 1개만 찾아 반환(문서 작성시 id값은 유일값을 가질 수 있도록 제작)

<button type="button" id="myBtn">내 버튼</button>

<script type="text/javascript">
	var myBtn = document.getElementById('myBtn');
	console.log(myBtn,{myBtn}, '아이디 검색하여 객체 반환');
	myBtn.onclick = function() {
		console.log(this); //this=버튼자체
		console.log('클릭 이벤트 등록');
	}		
</script>

 

class 검색

- html 요소 중 class 속성을 가진 대상 검색
- class 속성의 값 중 일치하는 대상 검색
- class의 값은 html요소 중 여러 대상이 동일한 값을 가질 수 있음으로 검색 후 반환되는 결괏값은 배열이다.
- api : document.getElementsByClassName('클래스명');

- 특징 : 그룹핑 가능

<style>
	.my-div{width: 100px; height: 100px; background-color: #000;}
</style>
<div class="my-div"></div>
<div class="my-div"></div>
<div class="my-div"></div>
<script type="text/javascript">
	var myDiv = document.getElementsByClassName('my-div');
	console.log(myDiv);
	//클래스를 검색 했을 경우 배열로 반환되어 오기 때문에
	//documnet api를 활용하기 위해서는 배열 원소(요소)까지 접근해야 한다.
	for(var i=0; i<myDiv.length; i++){
		myDiv[i].onclick = function() {
			this.style.backgroundColor = '#f00';
		}
	}
</script>

 

tag 검색

- html 요소 중 tag명으로 요소를 검색 할 수 있다.
- 동일한 태그가 있을 수 있음으로 검색된 결괏값은 배열이다.
- api : document.getElementsByTagName('태그명');

<h3>제목1</h3>
<h3>제목2</h3>
<h3>제목3</h3>

<script type="text/javascript">
	var h3Array = document.getElementsByTagName('h3');
	console.log(h3Array);
	
	for(var i=0; i<h3Array.length; i++){
		h3Array[i].onclick = function() {
			this.style.color = '#f00';
		}
	}
	
</script>

 

더보기

문제

backColor라는 아이디를 가진 버튼을 클릭시 body태그의 배경색상이
'빨강', '초록', '파랑'으로 순환되며 배경색상이 변경되도록 하여라
<button type="button" id="backColor">배경색상전환</button>

풀이

var colorArr = ['#f00', '#0f0', '#00f'];
var btn = document.getElementById('backColor');
var mybody = document.getElementsByTagName('body'); //배열로 반환
console.log(mybody);
var i = 0;
btn.onclick = function() {
	mybody[0].style.backgroundColor = colorArr[i];
	i++;
	if(i==colorArr.length) i=0;
   //원래 if(i==3) 이라고 조건식 썼음.. 
}

> mybody의 style을 못 가져오길래 계속 고민했는데 getElementsByTagName이라 body태그는 하나이지만 배열로 반환되어 가져오지 못한거였음... mybody에 인덱스 [0] 추가해서 해결

더보기

문제

<button type="button" class="tab">탭1</button>
<button type="button" class="tab">탭2</button>
<button type="button" class="tab">탭3</button><br>
<div class="tab-contant">콘텐츠1</div>
<div class="tab-contant" style="display: none;">콘텐츠2</div>
<div class="tab-contant" style="display: none;">콘텐츠3</div>

첫번째 풀이 - 실패

var tab = document.getElementsByClassName('tab');
var contant = document.getElementsByClassName('tab-contant');
console.log(tab);
console.log(contant);

for(var i=0; i<tab.length; i++){
	tab[i].onclick = function() {
    	console.log(i);
    }
}

> tab과 tab-contant의 인덱스 값이 똑같기 때문에 누른 버튼의 인덱스값과 같은 tab-contant 인덱스값만 보여주면 된다고 생각함 우선 버튼이 눌렸을 때 인덱스 값이 잘 나오는지 보고싶어서 console창에 출력해볼려고 하니 계속 3값만 나오게됨. 선생님의 크로져 설명을 듣고 다시 풀어봄

 

크로져 - 함수 실행 시 주위 환경을 기억하고 있다.

//1. 이렇게 하면 1초 뒤 j가 10이 돼서 10이 10번 찍힘
for(var j=0; j<10; j++){
	setTimeout(function(){
		console.log(j)
	}, 1000); 
}

/*2. setTimeout함수를 함수로 한번 감싸주고,
익명함수를 바로 실행할 수 있게 괄호로 그 함수를 감싸줌
이렇게 하면 1초뒤 0에서부터 9가 순차적으로 찍힘*/
for(var j=0; j<10; j++){
	(function(k){setTimeout(function(){
		console.log(k)
	}, 1000);})(j)
}

 

두번째 풀이

var tab = document.getElementsByClassName('tab');
var contant = document.getElementsByClassName('tab-contant');

for(var i=0; i<tab.length; i++){
	(function(n){tab[n].onclick = function(){
		//console.log(contant[n]); -> 버튼의 인덱스 값에 맞게 contant값이 잘 나오나 확인
		
  // 보여지는 contant[n] 외의 다른 인덱스값들의 contant를 안보여지게 하기위해 모두 none으로
        for(var j=0; j<contant.length; j++){
			contant[j].style.display='none';
		}
        
		contant[n].style.display = 'block';
	}
	})(i); //크로져 사용
}

선생님 풀이

var tabArr = document.getElementsByClassName('tab');
var contantArr = document.getElementsByClassName('tab-contant');

//매개변수로 겉의 for문의 i값을 쓰는 배열 원소 써버리기...
for(var i=0; i<tab.length; i++){
	(function(n, tab, contant){tab.onclick = function(){
		
        for(var j=0; j<contant.length; j++){
			contant[j].style.display='none';
		}
		
		contant.style.display = 'block';
	}
	})(i, tabArr[i], contantArr[i]);
}

 

선택자 검색

1. 단일 검색

 - html 요소 중 인수에 해당되는 선택자와 일치하는 대상 검색
 - 다중 대상을 검색하더라도 객체 하나만 반환한다.
 - api : document.querySelector('선택자');
 - api : 검색된대상객체.querySelector('선택자');

2. 다수 검색

 - html 요소 중 인수의 선택자에 해당되는 모든 객체를 검색하여 배열로 반환
 - api : document.querySelectorAll('선택자');
 - api : 검색된대상.querySelectorAll('선택자');

 

 

❗❗ 선택자 종류에 따라 맞는 기호와 and,or 조건 등을 활용하여 사용할 수 있다

var divWrap2 = document.querySelector('#divWrap2');
var liArray = divWrap2.querySelectorAll('li');
 ↓ ↓ ↓
var liArray = document.querySelectorAll('#divWrap2 li');

 

 

그 외 document API와 Element

종류 설명
remove( ) 선택된 대상 제거
children 하위요소 1단계 아래 태그 전체를 배열로 반환
childNodes 하위요소 1단계 아래 태그 및 텍스트 요소 전체를 배열로 반환
parentNode 상위요소 반환
parentElement 상위요소 반환(Element타입의 node만 반환)
innerHTML - 선택된 대상의 하위 html요소를 가져오거나 교체
- 삽입시 문자열을 html요소로 파싱시켜 삽입(복합대입연산자로 화면에 표나 리스트 만들기 가능)
innerText 선택된 대상의 하위 텍스트 요소만 가져오거나 삽입
createElement( ) Element 생성시 쓰이는 메서드 - 객체를 생성하더라도 화면에 반영 되지 않고,
 트리구조로 정의된 사이에 추가해야 한다
createTextNode( ) 텍스트 요소 생성시 쓰이는 메서드
appendChild( ) - 선택된 대상의 하위요소에 생성된 혹은 선택된 대상을 추가
- 문자열로 만들어진 대상은 추가되지 않는다. (넣고 싶으면 변수로 만들어서)
setAttribute(속성명, 속성값) 선택된 대상에 속성 추가
getAttribute( ) 선택된 대상의 속성 값 가져오기
removeAttribute( ) 선택된 대상의 속성값 제거
classList 선택된 대상에서 classList 속성에 접근하여 클래스를 추가하거나 제거 할 수 있다
add(추가메서드), remove(제거메서드), toggle(추가,제거 순환 메서드)

 

더보기

실습1. 버튼 클릭시 해당 버튼의 행이 제거 될 수 있도록 하시오

<table border="1">
	<tbody>
		<tr>
			<td>제목</td>
			<td>
				<button type="button" class="tr-remove">제거</button>
			</td>
		</tr>
		<tr>
			<td>제목</td>
			<td>
				<button type="button" class="tr-remove">제거</button>
			</td>
		</tr>
		<tr>
			<td>제목</td>
			<td>
				<button type="button" class="tr-remove">제거</button>
			</td>
		</tr>
	</tbody>
</table>

풀이

var btn = document.querySelectorAll('.tr-remove');
for(var i=0; i<btn.length; i++){
	btn[i].onclick = function(){
		this.parentNode.parentNode.remove();
	}
}

> 처음에 parentNode나 parentElement 쓸 생각 못하고 위에 탭 기능 구현 처럼 그럼 tr하고 버튼 배열로 받아서 인덱스 값 똑같게 하면 되겟다 하고 막막하게 소스 쓰다가 선생님이 아주 간단한 문제라고 해서 당황했다... 사실 이 때 깃허브 commit 내역이 날라가서 멘붕이였던 터라..^^ 마지막 remove메서드 생각안나서 결국 못풀었던 문제... 

더보기

실습1. 아래의 버튼을 클릭시 name속성에 userName이라는 값을 가진 input태그가 body태그 하위의 제일 마지막에 생성될 수 있도록 코드를 작성하고 실행하시오. (input 태그는 사용자가 사용자명을 입력할 수 있어야 한다.)

<button type="button" id="addHtml01">객체 생성01</button>

풀이

var btn01 = document.querySelector('#addHtml01');
var body = document.querySelector('body');
var myInput = document.createElement('input');
console.log(myInput);

btn01.onclick = function(){
	body.appendChild(myInput);
	myInput.setAttribute('type','text');
	myInput.setAttribute('name', 'userName');
	console.log(myInput);
}

> 화면에 추가만 버튼누르면 되는줄 알았는데 아예 생성까지도 버튼을 누르면 되게 하라는 거였다.. 문제 이해 언제 제대로 하게 될까 createElement코드만 버튼 클릭시 함수블럭 안으로 옮기면 됨

 

 

실습2. 아래의 버튼을 클릭시 테이블을 행이 추가 될 수 있도록 하여라

<table border="1">
	<thead>
		<tr>
			<th>제목</th>
		</tr>
	</thead>
	<tbody id="addRow">
		<tr>
			<td>공지사항</td>
		</tr>
	</tbody>
</table>
<button type="button" id="addRowBtn">행추가</button>

풀이1 (선생님이 쓰라고 한 api 이용)

var tbody = document.querySelector('#addRow');
var btn02 = document.querySelector('#addRowBtn');

btn02.onclick = function(){
	var tr = document.createElement('tr');
	var td = document.createElement('td');
	tbody.appendChild(tr);
	tr.appendChild(td);
	td.innerText = '내용';
	console.log(tbody.innerHTML);
}

풀이2 (innerHTML 사용한 풀이)

var tbody = document.querySelector('#addRow');
var btn02 = document.querySelector('#addRowBtn');

btn02.onclick = function(){
	tbody.innerHTML += '<td>내용</td>';
	console.log(tbody.innerHTML);
}

> 새로운 변수를 만들어 복합대입연산자로 한줄 한줄 씩 태그를 쓰고 그걸 innerHTML에 대입하면 제대로 돌아가는데, 그냥 innerHTML에 계속 복합대입연산자로 한줄한줄쓰면 태그끼리만 붙어버리고 텍스트는 뒤로 빠져버림.. 그리고 tr태그는 td태그를 생성하면 자동으로 생성돼서 따로 써줄 필요없음

 

실습3. 아래의 버튼 클릭시 해당 행의 텍스트를 ksmart로 변경하도록 하시오

<table>
	<tbody>
		<tr>
			<td>
				<input type="text" value="한국스마트정보교육원">
			</td>
			<td>
				<button type="button" class="changeTextBtn">변경</button>
			</td>
		</tr>
		<tr>
			<td>
				<input type="text" value="한국스마트정보교육원">
			</td>
			<td>
				<button type="button" class="changeTextBtn">변경</button>
			</td>
		</tr>
		<tr>
			<td>
				<input type="text" value="한국스마트정보교육원">
			</td>
			<td>
				<button type="button" class="changeTextBtn">변경</button>
			</td>
		</tr>
	</tbody>
</table>

풀이1 (parentElement,children, querySelector 사용해서)

var btn03 = document.querySelectorAll('.changeTextBtn');

for(var i=0; i<btn03.length; i++){
	btn03[i].onclick = function(){
		var tr = this.parentElement.parentElement;
		//var input = tr.children[0].children[0];
        	var input = tr.querySelector('input');
		//input.setAttribute('value', 'ksmart');
        	input.value = 'ksmart';
	}
}

> input은 children이 아니라 querySelector쓰는게 나음, value='ksmart' 이렇게 써도됨

풀이2 (크로져 사용해서)

var btn03 = document.querySelectorAll('.changeTextBtn');
var input = document.querySelectorAll('table input');

for(var i=0; i<btn03.length; i++){
	(function(n){btn03[n].onclick = function(){
		input[n].value= 'ksmart';
	}})(i);	
}

 

실습4. 버튼 클릭시 해당 행을 제거 하시오.

<ul>
	<li>
		<button type="button" class="removeBtn">제거1</button>
	</li>
	<li>
		<button type="button" class="removeBtn">제거2</button>
	</li>
	<li>
		<button type="button" class="removeBtn">제거3</button>
	</li>
</ul>

풀이

var btn04 = document.querySelectorAll('.removeBtn');
for(var j=0; j<btn04.length; j++){
	btn04[j].onclick = function() {
		this.parentElement.remove();				
	}
}

 

728x90