<!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>
div {
border: 1px solid black;
padding: 5px 10px;
margin: 5px;
}
#n7 {
border: 5px solid cornflowerblue;
}
.sel {
border: 5px solid tomato;
}
</style>
</head>
<body>
<div id="n1">할아버지
<div id="n2">큰아버지
<div id="n5">사촌</div>
</div>
<div id="n3">아버지
<div id="n6">형</div>
<div id="n7">나
<div id="n10">첫째 자식</div>
<!-- 기준 요소 -->
<div id="n11">둘째 자식
<div id="n13">손자</div>
</div>
<div id="n12">셋째 자식</div>
</div>
<div id="n8">동생</div>
</div>
<div id="n4">작은아버지
<div id="n9">사촌</div>
</div>
</div>
<hr>
<input type="button" value="확인" id="btn1">
<script>
/*
Axis 검색
- 상대 검색
- 나(기준)를 중심으로 다른 노드를 찾는 검색 방식
- 누구를 원점으로 하느냐에 따라 달라진다.
DOM Tree의 구성요소
- 페이지 소스의 모든 요소들이 구성요소가 된다.
- 선언문(<!DOCYPE>), 주석, 태그, PCDATA, 속성 등
*/
var btn1 = document.getElementById("btn1");
var n7 = document.getElementById("n7");
btn1.onclick = function() {
/*
Tree 구조에서 요소를 노드(Node)라고 부른다.
Element = 태그
내 자식들 검색 도구
- n7.hasChildNodes
- n7.childNodes
- n7.firstChild
- n7.lastChild
- n7.children
- n7.firstElementChild
- n7.lastElementChild
*/
alert(n7.hasChildNodes()); // 자식이 있습니까? - true/false(확인)
// 유사배열
alert(n7.childNodes.constructor); // 유사배열인지 확인 -> Array면 순수배열, function NodList() 생성자 함수
alert(n7.childNodes.length); // 내 자식이 몇명? > 7명 => 태그, PCDATA, tap(enter) 포함
/*
노드(Node)
- 태그, 속성, PCDATA, 주석, 선언문 등..
- 1. nodeType
- 해당 노드의 타입
- 태그(1)
- 속성(2)
- PCDATA(3)
- 주석(8)
- 선언문(13)
- 2. nodeName
- 태그(태그명)
- 속성(속성명)
- PCDATA(#text)
- 주석(#comment)
- 나머지(#xxxx)
- 3. nodeValue
- 태그(null)
- 속성(속성값)
- PCDATA(텍스트)
*/
for (var i=0; i<n7.childNodes.length; i++){
console.log('index', i);
// console.log(n7.childNodes[i]);
console.log('\tnodeType', n7.childNodes[i].nodeType); // 자식의 조합을 명확하게 알 수 있음.
console.log('\tnodeName', n7.childNodes[i].nodeName);
console.log('\tnodeValue', n7.childNodes[i].nodeValue);
}
/*
n7.childNodes > 모든 타입의 노드를 자식으로 취급
n7.children > 태그만 자식으로 취급
*/
console.log(n7.children.length);
for (var i=0; i<n7.children.length; i++){
console.log('nodeType', n7.children[i].nodeType);
console.log('nodeName', n7.children[i].nodeName);
}
n7.firstElementChild.className = "sel";
n7.lastElementChild.className = "sel";
};
// 덮어쓰기, 재정의
// var a = 10;
// a = 5;
// 위의 상황과 같은 상황 ↓
btn1.onclick = function() {
/*
부모 탐색
- n7.parentNode
- n7.parentElement
*/
n7.parentNode.className = "sel"; // 아버지
n7.parentNode.parentNode.className = "sel"; // 할아버지
n7.parentNode.parentNode.parentNode.className = "sel"; // 증조할아버지
n7.parentNode.parentNode.parentNode.parentNode.className = "sel"; // 고조할아버지
// <html> 노드의 부모
// - 화면에 안보이는 노드
// - window.document 객체
n7.parentNode.parentNode.parentNode.parentNode.parentNode.className = "sel"; // 현조할아버지
alert(n7.parentNode.parentNode.parentNode.parentNode.parentNode.nodeName); // document
alert(n7.parentNode.parentNode.parentNode.parentNode.parentNode.nodeType); // 9
alert(n7.parentNode.parentNode.parentNode.parentNode.parentNode === window.document); // true
// BOM : document의 부모는 window이다.
// DOM : document가 최상위 객체이다.
// alert(n7.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.nodeName); // window?? -> 에러!!!!
};
btn1.onclick = function() {
// 형제를 찾으려면 부모로 올라가서 찾아야한다.
// 형제 찾기
//n7.parentNode.firstElementChild.className = "sel";
n7.previousElementSibling.className = "sel";
// 동생 찾기
//n7.parentNode.lastElementChild.className = "sel";
n7.nextElementSibling.className = "sel";
};
/*
패턴
- 1. id 검색 > 나를 검색
- 2. 나를 중심 > axis 검색
*/
</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>
<h1>속성 제어</h1>
<a href="http://google.con" id="link1">구글</a>
<hr>
<input type="button" value="버튼" id="btn1">
<script>
var link1 = document.getElementById('link1');
var btn1 = document.getElementById('btn1');
btn1.onclick = function() {
/*
< 속성 제어 >
1. BOM
- HTML의 속성을 JavaScript에서 프로퍼티로 제공한다.
*/
// link1.href = 'http://w3.org'; // 속성 제어
// link1.target = '_blank'; // 없는 속성 추가
// link1.innerText = 'W3C' // DOM으로 PADATA 조작
/*
2. DOM
- setter(), getter() 제공
*/
// link1.setAttribute('속성이름','속성값');
// link1.setAttribute('href','http://daum.net'); // 속성 제어
// alert(link1.getAttribute('href')); // 확인. 속성값 반환
// link1.setAttribute('target', '_blank');
// link1.textContent = '다음';
alert(link1.attributes.length); // 2 -> link1가 속성을 2개 가지고 있다(href, id)
for(var i=0; i<link1.attributes.length; i++) {
console.log('nodeName', link1.attributes[i].nodeName);
console.log('nodeType', link1.attributes[i].nodeType);
console.log('nodeValue', link1.attributes[i].nodeValue);
}
// DOM에서의 속성 제어 인터페이스
// link1.attributes - 모든 속성을 총괄. 배열
// link1.setAttribute - 추가
// link1.getAttribute - 확인
// link1.removeAttribute('href'); // 속성 없애기
// link1.toggleAttribute('href'); // 해당 속성을 넣었다 뺐다 할 수 있음
};
</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>
<!-- 태그 조작 -->
<input type="button" value="버튼" id="btn1">
<hr>
<div id="div1"></div>
<hr>
<div id="cat">
<img src="images/catty01.png">
<img src="images/catty02.png">
<img src="images/catty03.png">
<img src="images/catty04.png">
<img src="images/catty05.png">
</div>
<script>
var btn1 = document.getElementById('btn1');
var div1 = document.getElementById('div1');
// DOM을 사용해서 태그 + 속성 + PCDATA 조작
// - 생성
// - 제어
// - 삭제
btn1.onclick = function() {
/*
<a href ="http://naver.com">네이버</a>
BOM -> 불가능
DOM -> 가능
*/
// DOM
// innerHTML -> 간단함. 불편함(의미없는 텍스트 조작)
div1.innerHTML = "<a href='http://naver.com'>네이버</a>";
// 표준 방법, 정석(******) -> 조직화, 대형화 작업에서 편리
// 노드(태그)만들기
var a = document.createElement('a'); // <a> 생성
// alert(a.nodeType); // 1
// alert(a.nodeName); // A
// 속성 만들기
// href = ''
var href = document.createAttribute('href');
// href = 'http://naver.com'
href.nodeValue = 'http://naver.com';
// 태그와 속성 연결하기
// <a href='http://naver.com'></a>
// a.setAttribute('name', 'value');
a.setAttributeNode(href);
// PCDATA 만들기
var text = document.createTextNode('네이버');
// 태그와 PCDATA 연결하기
a.appendChild(text);
// 확인 -> 화면에 안보임
console.log(a);
// 화면에 출력 -> 이미 화면에 보이고 있는 태그(div)의 자식으로 넣어야한다.
div1.appendChild(a);
};
// ---------------------------------------------------------------------------------
// 간단 버전 (***)
btn1.onclick = function() {
// 태그만들기
var a = document.createElement('a');
// 속성만들기
a.setAttributeNode('href', 'http://naver.com');
// PCDATA 만들기
a.innerHTML = '네이버';
// 연결하기
div1.appendChild(a);
};
btn1.onclick = function() {
//링크 X 3개
// 객체 배열
var data = [
{ // 객체
name: '네이버',
url: 'http://naver.com'
},
{
name: '구글',
url: 'http://google.com'
},
{
name: '다음',
url: 'http://daum.net'
}
];
data.forEach(function(item, index) {
// alert(item.name + ',' + item.url);
// BOM
div1.innerHTML += "<a href='"+ item.url +"'>" + item.name +"</a><br>";
// DOM
var a = document.createElement('a');
a.setAttributeNode('href', item.url);
a.innerText = item.name;
div1.appendChild(a);
var br = document.createElement('br');
div1.appendChild(br);
});
};
btn1.onclick = function() {
// img의 부모 -> #cat
var cat = document.getElementById('cat');
// img - 유사배열
for(var i=0; i<cat.children.length; i++) {
// cat.children[i].width = 50;
cat.children[i].onclick = function() {
cat.removeChild(event.srcElement); // 태그 삭제
};
}
// DOM에서 태그 삭제 > 부모가 한다.
// cat.removeChild(자식 태그);
// cat.removeChild(cat.firstElementChild);
// cat.removeChild(cat.lastElementChild);
// cat.removeChild(cat.Children[2]);
};
</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>
<h1>DOM 이벤트</h1>
<input type="button" value="버튼" id="btn1">
<script>
var btn1 = document.getElementById('btn1');
function m1(){
alert('m1');
}
function m2(){
alert('m2');
}
function m3() {
m1();
m2();
}
// BOM 이벤트
// btn1.onclick = function() {}; // 익명함수
// btn1.onclick = m1; // 실명함수. 덮어쓰기
// btn1.onclick = m2; // 덮어쓰기
// btn1.onclick = null; // 이벤트 제거
// btn1.onclick = m1 + m2; // 불가능
// btn1.onclick = m3; // m1 + m2 -> 함수로 해결 -> 편법
// DOM 이벤트
// - addEventListener
// : 함수를 목록으로 관리한다.(InvocationList).(함수만 따로 관리하는 배열)
// : 리스트에 함수를 Append
// btn1.addEventListener('이벤트종류', 함수);
// btn1.addEventListener('click', function() { // 익명함수
// alert();
// });
btn1.addEventListener('click', m1); // 덮어쓰기. 실명함수
btn1.addEventListener('click', m2); // 덮어쓰기(X), 누적(O)
btn1.removeEventListener('click', m1); // 삭제 - 실명함수
</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>
<style>
#tbl1 {
border: 1px solid black;
border-collapse: collapse;
}
#tbl1 td {
border: 1px solid black;
width: 100px; height: 100px;
text-align: center;
}
</style>
</head>
<body>
<table id="tbl1">
<tr>
<td class="cell"></td>
<td class="cell"></td>
<td class="cell"></td>
<td class="cell"></td>
<td class="cell"></td>
</tr>
<tr>
<td class="cell"></td>
<td class="cell"></td>
<td class="cell"></td>
<td class="cell"></td>
<td class="cell"></td>
</tr>
<tr>
<td class="cell"></td>
<td class="cell"></td>
<td class="cell"></td>
<td class="cell"></td>
<td class="cell"></td>
</tr>
<tr>
<td class="cell"></td>
<td class="cell"></td>
<td class="cell"></td>
<td class="cell"></td>
<td class="cell"></td>
</tr>
<tr>
<td class="cell"></td>
<td class="cell"></td>
<td class="cell"></td>
<td class="cell"></td>
<td class="cell"></td>
</tr>
</table>
<script>
var cell = document.getElementsByClassName('cell');
var index = 0;
cell[index].bgColor = 'gold';
// DOM에 이벤트 걸 때 -> onkeydown -> on빼기
window.addEventListener('keydown', function() { // window -> 전역으로 걸기
clear();
if (event.keyCode == 37) {
// 왼쪽 방향키
index--;
if (index < 0) {
//index = 0;
index = cell.length - 1;
}
} else if (event.keyCode == 39) {
// 오른쪽 방향키
// cell[index].bgColor = 'transparent'; // 투명색
index++;
if (index >= cell.length) {
// alert('마지막 셀입니다.');
// index--;
index = 0;
}
}
cell[index].bgColor = 'gold';
});
// 전체를 투명으로 바꾸는 함수
function clear() {
for (var i=0; i<cell.length; i++) {
cell[i].bgColor = "transparent";
}
}
</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>
<style>
.box { border: 1px solid black; padding: 50px; }
#box1 { background-color: tomato; }
#box2 { background-color: gold; }
#box3 { background-color: cornflowerblue; }
.tbl { border: 1px solid black; border-collapse: collapse; }
.tbl td { border: 1px solid black; }
#tbl1 { margin: 20px 0; }
#tbl1 td { padding: 5px 20px; }
#tbl2 td { width: 126px; height: 126px; }
#tbl2 td img { display: block; }
</style>
</head>
<body oncontextmenu="return false;"> <!-- contextmenu없앰(마우스 우측버튼 - 메뉴창) -->
<h1>이벤트 버블링(Event Bubbling), 이벤트 터널링(Event Tunneling) == 이벤트 캡처링(Event Capturing)</h1>
<table id="tbl2" class="tbl">
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>
<table id="tbl1" class="tbl">
<tr>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
</tr>
<tr>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
</tr>
<tr>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
</tr>
<tr>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
</tr>
<tr>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
</tr>
<tr>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
</tr>
<tr>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
</tr>
<tr>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
</tr>
<tr>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
</tr>
<tr>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
</tr>
</table>
<div id="box1" class="box">
<div id="box2" class="box">
<div id="box3" class="box"></div>
</div>
</div>
<script>
// JavaScript의 이벤트는 기본적으로 버블링을 기반으로 동작한다.(*****)
// 터널링 기반의 동작은 지원하지 않는다.(추가 지원함)
var box1 = document.getElementById('box1');
var box2 = document.getElementById('box2');
var box3 = document.getElementById('box3');
// box3.onclick = function() {
// alert('손자')
// //alert(event.srcElement.id);
// // 부모로 전파되는 버블링을 취소
// //event.cancelBubble = true;
// };
// box2.onclick = function() {
// alert('부모');
// //alert(event.srcElement.id);
// //event.cancelBubble = true;
// };
// box1.onclick = function() {
// alert('조부모');
// //alert(event.srcElement.id);
// //event.srcElement.style.border = "10px solid black";
// };
// true -> 터널링 / false -> 버블링
// box1.addEventListener('click', function() {
// alert('할아버지');
// }, true);
// box2.addEventListener('click', function() {
// alert('아버지');
// }, true);
// box3.addEventListener('click', function() {
// alert('나');
// }, true);
// -------------------------------------------------------------------
// var td = document.getElementsByTagName('td');
// for (var i=0; i<td.length; i++) {
// td[i].onmouseover = function() {
// event.srcElement.bgColor = 'gold';
// };
// td[i].onmouseout = function() {
// event.srcElement.bgColor = 'transparent';
// };
// }
// 행 단위로 색상 바꾸기
// var tr = document.getElementsByTagName('tr');
// for (var i=0; i<tr.length; i++) {
// tr[i].onmouseover = function() {
// 테이블에서는 영역이 겹치기 때문에 무조건 event.srcElement는 td에 걸리게 된다.
// // event.srcElement.bgColor = 'gold';
// // event.srcElement.parentNode.bgColor = 'gold'; // td의 부모인 tr을 찾기
// event.currentTarget.bgColor = 'tomato'; // 함수를 소유하고 있는 이벤트의 주인을 가르킴
// };
// tr[i].onmouseout = function() {
// // event.srcElement.bgColor = 'transparent';
// // event.srcElement.parentNode.bgColor = 'transparent';
// event.currentTarget.bgColor = 'transparent';
// };
// }
// ---------------------------------------------------------------------------
var td = document.getElementsByTagName('td');
for (var i=0; i<td.length; i++) {
td[i].onmousedown = function() {
// event.srcElement -> <td>
// event.srcElement.innerHTML = '<img src="images/rect_icon01.png">';
// event.srcElement.firstElementChild.onmousedown = function() {}; // img
// 마우스 왼쪽버튼 누르면 추가
if (event.buttons == 1) {
// 객체 찾기 쉬움.
var img = document.createElement('img');
img.setAttribute('src', 'images/rect_icon01.png');
event.srcElement.appendChild(img);
} else if (event.buttons == 2) { // 마우스 오른쪽 버튼 누르면 삭제
// 이미지 삭제
// alert(event.srcElement.nodeType);
// alert(event.srcElement.nodeName); // img
// event.srcElement.removeChild(event.srcElement.firstElementChild);
// event.srcElement.parentNode.removeChild(event.srcElement);
event.currentTarget.removeChild(event.currentTarget.firstElementChild); // event.currentTarget -> <td>
}
// img.onmousedown = function() {
// //클릭한 이미지를 삭제
// event.srcElement ->img
// event.srcElement.parentNode -> td
//부모가 자식을 없앨 수 있음.
// event.srcElement.parentNode.removeChild(event.srcElement);
// };
};
}
</script>
</body>
</html>