UI Laboratory

UI 개발을 위한 레퍼런스

INDEX

노드 다루기


			<!DOCTYPE html PUBLIC "-//W3C//DTD Xhtml 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
			<html>
			<head>
				<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
				<title>
				<style>
					body{
						font-size:9pt;
						font-family:"굴림";		
					}
					div, p{
						border:1px #eeeeee solid;
						margin:10px;
					}
				</style>
			</head>
				
			<body>
				<div id="sample_page" class="page" >
					샘플 페이지(div, id=sample_page, class=page)
					<div id="header">				
						헤더 영역(div, id=header)
					</div>
					<div id="content" class="sample_content">
						컨텐츠 영역(div, id=content, class=sample_content)
						<div> 
							JavaScript란?(div)
							<p id="data_1">1. 자바스크립트 Core(p, id=data_1)

<p id="data_2">2. 자바스크립트 BOM(p, id=data_2)

<p id="data_3">3. 자바스크립트 DOM(p, id=data_3)

을 배운다는것 </div> <div class="content_data"> 자바스크립트에서 배울 내용(div, class=content_data) <p>1. 자바스크립트 DOM(p)

<p>2. 자바스크립트 Ajax(p)

</div> <div class="content_data"> jQuery에서 배울 내용(div, class=content_data) <p>1. jQuery DOM(p)

<p>2. jQuery Ajax(p)

</div> </div> <div id="footer"> 푸터 영역(div, id=footer) </div> </div> </body> </html>

문서에서 특정 태그 이름을 지닌 노드 찾기

Document 객체의 getElementByTagName()을 이용하면 전체문서에서 특정 태그 이름을 모두 찾을 수 있다.

ex) 전체 문서에서 태그 이름이 div인 엘리먼트를 찾아 각 엘리먼트의 border를 4px solid #ff0000로 스타일을 변경하려면?

			// 전체문서에서 태그이름이 div인 Element Node찾기
			var divs = window.document.getElementsByTagName("div");
			alert("전체문서에서 div 엘러먼트 갯수 : "+divs.length);
			
			for(var i=0;i< divs.length;i++){
				// 찾은 노드에서 n번째 노드를 접근해서 
				var div = divs.item(i);
				// 스타일 변경하기.
				div.style.border= "4px solid #ff0000";
			}
		

NodeList 객체

getElementsByTagName()의 결과 값은 검색된 모든 노드를 NodeList라는 객체에 담아 반환된다. NodeList는 배열과 비슷한 일종의 컬렉션 객체이다. NodeList객체의 length 프로퍼티에는 결과값의 전체 개수 정보가 담겨 있으며, item()은 특정 항목에 접근 할 수 있다. item() 대신 배열을 사용하듯 divs[0]과 같은 식으로도 특정 항목에 접근 할 수 있다.

특정 노드의 자식 노드에서 특정 태그 이름을 지닌 노드 찾기

문서 전체가 아닌 특정 노드의 자식 노드 가운데 특정 태그 이름을 가진 엘리먼트를 찾고 싶을 경우 Document 객체의 메서드인 getElementsByTagName() 대신 Element 객체의 메서드인 getElementsByTagName()을 사용한다.

ex) 전체 문서에서 태그 이름이 div인 엘리먼트를 찾아 찾은 노드 가운데 2번째 노드의 자식 노드 중 태그 이름이 div인 엘리먼트의 border를 1px solid red로 스타일을 변경하려면?

			var divs = window.document.getElementsByTagName("div");
			// 찾은 node에서 2번째 노드의 자식노드중에서 div태그 이름을 가진 엘리먼트 찾기.
			var div2 = divs[2];	
			var div2Child = div2.getElementsByTagName("div");		
			for(var i=0;i< div2Child.length;i++){
				div2Child[i].style.border = "4px solid red";
			}		
		

문서에서 특정 클래스가 적용된 노드 찾기

Document 객체의 getElementsByClassName()을 사용한다.

ex) 전체 문서에서 content_data라는 클래스가 적용된 엘리먼트를 찾아 border가 1px solid red인 스타일을 변경하려면?

			var contentData = window.document.getElementsByClassName("content_data");
			for(var i=0;i< contentData.length;i++){
				contentData[i].style.border = "4px solid red";
			}		
		

getElementsByClassName()은 익스플로러9 이하 버전을 제외한 모든 브라우저에서 정상적으로 동작한다.

자식 노드 찾기

1. 자식 노드를 모두 구하고 싶을 때
먼저 특정 엘리먼트의 하위 노드인 자식 노드에 접근하고 싶을 때는 Node 객체의 프로퍼티인 childNodes를 사용한다.
2. 자식 노드중 N번째 노드에 접근하고 싶을 때
하위 노드 가운데 N번째 요소에 접근하고 싶다면 var node=page.childNodes[N] 또는 node=page.childNodes.item(N)과 같은 식으로 한다.
3. 첫번째 자식 노드에 바로 접근하고 싶을 때
Node에는 firstChild라는 프로퍼티가 있어서 이를 이용하면 자식 노드중 첫번째 자식 노드에 바로 접근할 수 있다.
4. 마지막 자식 노드에 바로 접근하고 싶을 때
Node에는 lastChild라는 프로퍼티가 있어서 이를 이용하면 자식 노드중 마지막 자식 노드에 바로 접근할 수 있다.

※ 눈에 보이지 않는 개행문자도 텍스트 노드에 포함된다. 단 인터넷 익스플로러9 이하 버전에서는 개행문자만 포함된 문자열은 텍스트 노드로 생성되지 않는다.

				/*
					자식 노드를 구하고 접근하기			
				*/
				
				//1. Element의 자식노드 찾기. childNodes 역시 NodeList객체랍니다.
				var page = window.document.getElementById("sample_page");
				var nodes = page.childNodes;
				alert("#sample_page의 자식노드 갯수는 ? "+nodes.length);
			
				//2. 자식 노드를 하나씩 접근하기.
				for(var i=0;i< nodes.length;i++){
					var node = nodes.item(i);
					
					//Node가 Element인 경우만 스타일을 변경시킨다.
					if(node.nodeType==1)
						node.style.border = "4px solid #ff0000";
				}
						
				//3. 첫번째 자식노드 접근하기.
				var firstChild = page.firstChild;
				// 현재 firstChild는 textNode이기 때문에 스타일을 적용할 수 없답니다.
				firstChild.style.color = "#ff0000";
				
				//4. 마지막번째 자식노드 접근하기.
				var lastChild = page.lastChild;
				// 현재 lastChild는 textNode이기 때문에 스타일을 적용할 수 없답니다.
		

부모 노드 찾기

특정 엘리먼트의 부모 노드에 접근하고 싶을 때는 Node 객체의 기본 프로퍼티인 parentNode를 사용한다.

예를 들면

형제 노드 찾기

Node의 previousSibling 프로퍼티를 이용하면 바로 앞의 형제노드를, nextSibling 프로퍼티를 이용하면 바로 뒤의 형제노드를 알아낼 수 있다.

			// 기준이 되는 #content를 구한 후
			var content = document.getElementById("content");

			//content 노드에서 형제 노드인 #header에 접근하기
			content.previousSibling.previousSibling.style.border = '1px solid red';
		

노드 생성 및 추가하기

노드를 생성하고 추가하는 방법은 세가지가 있다.

핵심 메서드 & 프로퍼티

  • - 노드 생성 : Document.createElement()
  • - 텍스트 노드 생성 : Document.createTextNode()
  • - 노드 정보 : HTMLElement.innerHTML
  • - 마지막 위치에 노드 추가 : Node.appendChild(추가노드);
  • - 특정위치에 노드 추가 : Node.insertBefore(추가 노드, 기준노드)
  • - 노드 복사하기 : Node.cloneNode();

Document.creatElement() 메서드를 사용하는 경우

Document객체의 createElement() 메서드를 사용해 노드를 생성하는 방법은 가장 일반적인 방법으로, 주로 간단한 노드를 생성할때 많이 쓴다.

ex) <p>추가내용1</p>를
<div id="sample_page" class="page">
샘플 페이지(div, id=sample_page, class=page) 사이에 추가하려면?

			var page = document.getElementById("sample_page");
			//1-1. 기준이 되는 위치찾기.
			var firstChild = page.firstChild;
			//1-2. <p>Element를 동적으로 생성.
			var p1 = document.createElement("p");		
			//1-3. textNode 생성.
			var text1 = document.createTextNode("추가내용1");
			//1-4. p1의 자식노드로 text1을 추가.
			p1.appendChild(text1);		
			p1.style.border	= "4px solid #ff0000";
			//1-5. p1을 #sample_page 첫번째 자식 노드 앞에 추가 
			page.insertBefore(p1, firstChild);	
		

ex) <div>
           생성할 노드가 많은 경우,
           <span>어떤 방법을?</span>
           사용해야 할까요?
     </div>를
<div id="content" class="sample_content"> 앞에 추가하려면?

			// 2-1. 기준이 되는 위치찾기.
			var content = document.getElementById("content");
			// 2-2. <div> Element를 동적으로 생성.
			var div1 = document.createElement("div");
			// 2-3. div의 내부 자식노드를  동적으로생성하기.
			var text2_1	= document.createTextNode("생성할 Node의 양이 많은 경우 ");
			var span = document.createElement("span");
			var spanText =  document.createTextNode("어떤 방법을 ");	
			span.appendChild(spanText);			
			var text2_2	= document.createTextNode("사용해야 할까요?");
			
			// 2-4. div의 자식노드로 컨텐츠들을 추가
			div1.appendChild(text2_1);
			div1.appendChild(span);
			div1.appendChild(text2_2);		
			div1.style.border = "4px solid #ff0000";
			
			//2-5.생성된 div1을 #content의 위쪽에 추가
			page.insertBefore(div1,content);
		

HTMLElement.innerHTML 프로퍼티를 사용하는 경우

HTMLElement객체의 innerHTML 프로퍼티는 Element의 내부에 들어 있는 모든 자식을 문자열로 담은 프로퍼티이다.

첫번째 영역에 추가하기
			var page = document.getElementById("sample_page");
			page.innerHTML = "

추가내용1

"+page.innerHTML;
두번째 영역에 추가하기
			var page = document.getElementById("sample_page");
			var content = document.getElementById("content");
			var div = window.document.createElement("div");
			div.style.border	= "4px solid #ff0000";
			div.innerHTML = "생성할 Node의 양이 많은 경우 어떤 방법을 사용해야 할까요?"
			page.insertBefore(div, content );
		
세번째 영역에 추가하기
			var page = document.getElementById("sample_page");
			page.innerHTML += "

추가내용2

";

아래처럼 읽기용으로 사용하면

			var page = document.getElementById("sample_page");
			var strHTML = page.innerHTML;
		

strHTML에는 page 내부의 모든 DOM 구조가 문자열로 변환되어 저장된다.

이와 달리 쓰기용으로 사용하면

			var page = document.getElementById("sample_page");
			var strHTML = "

신규노드

"; page.innerHTML = strHTML;

page.innerHTML에 문자열이 대입되는 순간 바뀐 innerHTML 정보를 가지고 파싱단계를 거쳐 태그와 일대일 매칭되는 DOM 객체를 생성한 후 화면에 출력해 준다. 즉, 새로 추가할 노드를 DOM 메서드를 이용해 일일이 생성하지 않고 문자열로 만들어 대입해 주기만 하면 된다.

Node.cloneNode() 메서드를 사용하는 경우

만약 생성하고 싶은 내용이 이미 생성돼 있는 요소와 똑같거나 다소 비슷하다면 Node객체에서 제공하는 cloneNode() 메서드를 이용해 똑같은 노드를 복사해서 생성할 수 있다.

			var page = document.getElementById("sample_page");
			//1-1. 기준이 되는 위치찾기.
			var firstChild = page.firstChild;
			//1-2.<p> Element를 동적으로 생성.
			var p1 = document.createElement("p");		
			//1-3. textNode 생성.
			var text1 = document.createTextNode("추가내용1");
			//1-4. p1의 자식노드로 text1을 추가.
			p1.appendChild(text1);		
			p1.style.border	= "4px solid #ff0000";
			//1-5. p1을 #sample_page 첫번째 자식 노드 앞에 추가 
			page.insertBefore(p1, firstChild);	

			//3-1. p1노드를 그대로 복사.
			var p2 = p1.cloneNode(true);
			//3-2. textNode를 수정.
			p2.firstChild.nodeValue="추가내용2";		
			//3-3. p2을 page마지막 위치에 추가.
			page.appendChild(p2);	
		

노드 삭제하기

지우려는 노드를 찾은 다음 Node 객체의 메서드인 removeChild()를 호출하여 지운다.

			//1. 지우려고 하는 노드가 포함된 부모 노드를 찾는다.
			var page = document.getElementById("sample_page");			
			//2. 지우려는 노드를 찾는다.
			var content = document.getElementById("content");
			//3. 부모노드의 removeChild() 메서드를 이용해 노드를 삭제한다.
			page.removeChild(content);
		

노드 이동시키기

이미 생성돼 있는 노드를 특정 위치로 옮기려면 appendChild(), insertBefore()를 사용하면 된다.

			//1. 이미 생성되어 있는 노드중 이동시킬 대상을 찾습니다.
			var header = document.getElementById("header");			
			//2.이동위치의 노드를 구합니다.
			var content = document.getElementById("content");
			//3.header을 content의 자식노드로 이동시킵니다.
			content.appendChild(header);
		

텍스트 노드 생성 및 추가하기

텍스트 노드를 생성하려면 Document 객체의 creatTextNode() 메서드를 이용하면 된다.

			//1. 텍스트 노드를 추가할 부모노드를 먼저 찾습니다.
			var content = document.getElementById("content");			
			//2. 텍스트 노드를 생성합니다.
			var newTextNode =  document.createTextNode("추가내용1");
			
			//3. 일반 노드처럼 appendChild를 이용해서 생성한 텍스트 노드를 추가 시켜 줍니다.
			content.appendChild(newTextNode);
		

텍스트 노드 내용 변경하기

텍스트 노드는 대부분 엘리먼트의 하위 노드에 존재하므로 먼저 수정하려는 텍스트 노드가 포함된 부모 노드를 찾아야 한다. 이렇게 찾은 대상에서 다시 한번 하위 노드인 텍스트 노드를 찾아 Node 객체의 프로퍼티인 nodeValue에 원하는 값을 대입하면 내용을 변경할 수 있다.

			//1. 텍스트 노드를 추가할 부모노드를 먼저 찾습니다.
			var header = document.getElementById("header");			
			header.firstChild.nodeValue='헤더의 내용이 변경되었죠?';
		

스타일 및 속성 다루기


			<html>
			<head>
				<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
				<title>
				<style>
					div{
						border:1px #000000 solid;
						margin:20px;
						font-size:24px;
					}
				</style>
				<script>
					window.onload=function(){
					/* 미션 1 : #test_1의 스타일중 color, fontSize 속성 값을 출력하세요. */
					var test1 = document.getElementById("test_1");
					// inline 스타일인 경우 style 객체의 속성에 접근하면 .
					alert(test1.style);				// [object CSSStyleDeclaration]
					alert(test1.style.color);		// rgb(255, 0, 0)
					alert(test1.style.fontSize);	// null  <- 인라인 스타일 속성이 아니기 때문에 접근 불가.
					
					// inline 스타일이 아닌 경우 스타일 접근하는 방법은 
					// getComputedStyle()함수를 이용해서 전체스타일을 구한 후,
					// 속성에  접근해야 됨, 단, 모든 값은 읽기전용.
					var style = window.getComputedStyle(test1,null);
					alert(style.fontSize);			// 24px;
					}
				</script>
			</head>

			<body>
				<div id="test_1" style="color:#ff0000"> 
					테스트1-1
				</div>
			</body>
			</html>
		

스타일 속성값 알아내기

style 프로퍼티는 엘리먼트에 적용된 스타일 속성 가운데 오직 인라인 스타일로 적용된 스타일 정보만 가지고 있으며, 이를 통해 인라인 스타일 정보에만 접근 할 수 있다.
			var test1 = document.getElementById("test_1");
			alert(test1.style.color); 
			// color 속성은 인라인 스타일에 작성돼 있어서 style 프로퍼티로 접근할 수 있다.
			alert(test1.style.fontSize);	
			//fontSize 속성은 인라인 스타일이 아닌 내부스타일 또는 외부스타일로 작성돼 있어서 접근할 수 없다.
		
인라인 스타일이 아닌 스타일 구문으로 엘리먼트에 적용된 스타일을 알아내고 싶다면 아래 구문을 이용한다.
			var test1 = document.getElementById("test_1");
			var style = window.getComputedStyle(test1,null);
			alert(style.fontSize); // 결과 : 24px;
		

스타일 속성값 설정하기

동적으로 태그 엘리먼트의 특정 스타일 속성값을 변경하려면 모두 style 프로퍼티를 사용한다.
			var test1 = document.getElementById("test_1");
			test1.style.position ="absolute";
			test1.style.left ="100px";
			test1.style.color = "#ff0000";
		
하지만 아래 구문은 style 프로퍼티로 접근할 수 없으므로
			var test1 = document.getElementById("test_1");
			test1.style.top = (parseInt(test1.style.top)+50)+"px";
		
아래와 같이 수정해야 한다.
			var test1 = document.getElementById("test_1");
			test1.style.top = "10px";
			test1.style.top = (parseInt(test1.style.top)+50)+"px";
		

스타일 속성 제거하기

style의 removeProperty() 메서드를 이용하면 스타일 속성을 제거할 수 있다. 이 역시 인라인 스타일 프로퍼티만 제거할 수 있다. 단, IE9 이하 버전에서는 removeProperty 메서드를 제공하지 않는다.
			var test1 = document.getElementById("test_1");
			test1.style.removeProperty("border");
			test1.style.removeProperty("margin");
		

속성값 알아내기

속성값을 구하는 방법은 Node 객체의 getAttribute() 메서드를 이용하는 방법과 Element 객체의 하위 객체에 각각 정의돼 있는 프로퍼티일 경우 직접 호출하는 방법이 있다.
			<div id="test_1" style="color:#ff0000;font-size:14px" data-value="data1"> 
				테스트1-1
			</div>
		
			var test1 = document.getElementById("test_1");
			
			// 모든 속성값이 담겨있는 객체
			alert(test1.attributes);
	
			alert(test1.getAttribute("id"));			// 결과 : test_1
			alert(test1.getAttribute("data-value"));	// 결과 : data1
			
			// 바로 접근하기.
			alert(test1.id);					// 결과 : test_1
		

속성값 설정하기

			var test1 = document.getElementById("test_1");
			
			// 기본적으로 제공하는 속성인 경우 바로 속성값 설정하기.		
			test1.className	="myClass";
			
			// 사용자 정의 속성인 경우 setAttribute()메소드를 이용해서 속성값 설정하기.
			test1.setAttribute("data-value", "new-data1");
		

이벤트 다루기


이벤트 단계

이벤트는 크게 3단계에 걸쳐 발생한다.
캡처(Capture)단계
가장 먼저 실행되는 단계로서, document에서 시작해 실제 이벤트를 발생시킨 타겟까지 이동한다. 이를 캡처링이라고 한다. 이때 리스너가 등록돼 있다면 등록된 리스너가 실행된다.
타겟(Target)단계
캡처 단계를 거쳐 실제 이벤트를 발생시킨 타겟에 도착한 상태를 말한다.
버블(Bubble)단계
타겟 단계까지 오면 이벤트 흐름은 다시 타겟 단계의 역순으로 움직이기 시작한다. 이 흐름을 버블링(bubbling)이라고 한다.

예를 들어, 사용자가 B에서 마우스를 클릭하는 순간 이벤트는

  1. 1. 캡처단계는 document → body → A → B 까지 이동되며, 캡처 단계에 등록된 이벤트 리스너를 실행한다.
  2. 2. 타겟단계를 거쳐
  3. 3. 버블단계에 접어든다. 흐름은 캡처 단계의 역순인 B → A → body → document 까지 이동하며 버블단계에 등록된 이벤트 리스너를 실행시키며 소멸된다.

Event 객체

Event 객체는 Event 인터페이스에 정의돼 있는 모든 기능이 실제 구현돼 있는 객체이다.
eventPhase
현재 이벤트의 위치에 관한 정보를 담고 있다.
  • 1 = capture단계
  • 2 = target단계
  • 3 = bubbling단계
type
발생한 이벤트 이름이다.
target
실제 이벤트를 발생시킨 대상이다.
currentTarget
캡처링 단계와 버블링 단계를 거치면서 만나게 되는 객체에 이벤트 리스너가 등록돼 있을 경우 리스너가 실행되는데, 이때 리스너를 가지고 있는 대상이 담겨 있다.
bubbles와 stopPropagation
bubbles 가 true라면 현재 발생한 이벤트는 버블링이 발생하는 이벤트이며 이때 버블링을 도중에 중지시켜야 하는 경우 stopPropagation() 메서드를 사용한다.
cancelable과 preventDefault()
cancelable 프로퍼티의 값이 true 인 경우 preventDefault()를 이용해 기본 행동이 실행되지 않게 취소할 수 있다.
			<input id="txt_1" value="입력방지" />
		
			txt_1.addEventListener("mousedown", on_MouseDown);
			function on_MouseDown(e){
				if(e.cancelable)
					e.preventDefault();
			}
		
위 예제는 input 엘리먼트의 mousedown 이후 기본 입력 포커스가 실행되지 않는다. 이로써 사용자에게서 입력을 받을 수 없는 기능을 만들 수 있다. 읽기 전용 속성인 readonly="true"와 비슷하지만 기본 행동자체를 중지시킨다.

리스너 추가하기

			<html>
			<head>
				<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
				<title>
				<script>
					window.onload=function()
					{
						
						/*
							이벤트 등록 방법 두가지.
								1. 이벤트 함수를 이용하는 경우 (DOM Level 0)
								2. Event Model을 이용하는 경우 (  DOM Level 2)
						*/
						
						var info= window.document.getElementById("info");
						// DOM Level 0방식으로 이벤트 리스너 등록하기.	
						var btn_1 = window.document.getElementById("btn_1");
						// 1-1. 일반 함수를 이벤트 리스너로 사용하는 경우.
						btn_1.onclick = this.on_Click;
						// 1-2. 임의의 함수를 이벤트 리스너로 사용하는 경우.
						btn_1.onmouseover = function(e){
							//alert("마우스가 over되었습니다. ");
							info.innerHTML+="마우스가 over되었습니다.<br>"	
						}
						
						// DOM Level 2방식으로 이벤트 리스너 등록하기.
						var btn_2 = window.document.getElementById("btn_2");		
						// 2-1. 일반 함수를 이벤트 리스너로 사용하는 경우.
						btn_2.addEventListener("click", this.on_Click,false);		
						// 2-2. 임의의 함수를 이벤트 리스너로 사용하는 경우.
						btn_2.addEventListener("mouseover",function(e){
							//alert("마우스가 over되었습니다.");		
							info.innerHTML+="마우스가 over되었습니다.<br>"	
						},false);			
					}
					
					function on_Click(e){			
						info.innerHTML+="버튼이 click되었습니다.<br>"
					}
				</script>
			</head>
				<body>
					<button id="btn_1">DOM Level 0방식 테스트 - 마우스를 올려보거나 클릭 보세요.</button><br>
					<button id="btn_2">DOM Level 2방식 테스트 - 마우스를 올려보거나 클릭 보세요.</button><br>
					<div id="info">이곳에 이벤트 이벤트 정보가 출력됩니다.</div>
				</body>
			</html>
		
이벤트를 등록하는 방법은 두가지가 있다.
  1. 1. Dom Level 0 방식 : 이벤트 핸들러에 특정 함수를 설정
  2. 2. Dom Level 2 방식 : 이벤트 모델 방식을 이용해 특정 함수를 이벤트 리스너로 등록
그리고 이벤트 발생시 실행할 이벤트 리스너를 지정하는 방법도 두가지 이다.
  1. 1. 특정 이름을 지닌 일반함수를 이벤트 리스너로 사용
  2. 2. 이름이 없는 익명함수를 이벤트 리스너로 사용
IE9 이하 버전에서는 아래처럼 addEventListener 메서드 대신 attachEvent 메서드를 사용해야 한다.
			btn_2.attachEvent("onclick", this.on_Click);		
			// 2-2. 임의의 함수를 이벤트 리스너로 사용하는 경우.
			btn_2.attachEvent("onmouseover",function(e){
				info.innerHTML+="마우스가 over되었습니다.
" });

리스너 삭제하기

등록된 리스너 가운데 사용하지 않는 리스너는 삭제해야 한다.
DOM Level 0 방식
이벤트 리스너를 btn_1.onClick=on_Click 처럼 설정했다면 이벤트 삭제는 btn_1.onClick=null;
DOM Level 2 방식
이벤트 리스너를 btn_1.addEventListener('click', on_click, false)로 등록했다면 btn_1.removeEventListener('click', on_click, false)처럼 이벤트 리스너를 제거 할 수 있다. 단, DOM Level2에서는 익명함수를 만들어 사용한 경우 제거할 수 없다.
IE9 이하 버전에서는 아래처럼 removeEventListener 메서드 대신 detachEvent 메서드를 사용해야 한다.
			btn_2.detachEvent("onclick", this.on_Click);		
			// 2-2. 임의의 함수를 이벤트 리스너로 사용하는 경우.
			btn_2.detachEvent("onmouseover",function(e){
				info.innerHTML+="마우스가 over되었습니다.
" });

이벤트 발생시키기

click과 mouseover와 같은 이벤트를 브라우저가 아닌 개발자가 동적으로 직접 발생시킬 필요가 있다.
이럴때는 다음과 같은 순서로 작성을 한다.
  1. 1. document의 createEvent() 를 이용해 발생시키려는 이벤트 객체를 생성한다.
  2. 2. 이벤트와 함께 담아서 보낼 데이터를 이벤트 객체에 추가한다.
  3. 3. 1번에서 생성한 이벤트 객체의 initEvent()를 호출해 이벤트를 초기화한다.
  4. 4. 생성한 이벤트 객체를 dispatchEvent()의 매개변수 값으로 전달해 실행한다.
다음 예제는 #btn_1을 클릭하면 #btn_2에 click 이벤트를 동적으로 발생시켜 #btn_2를 클릭하지 않아도 클릭한 것처럼 만든다.
			<html>
			<head>
				<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
				<title></title>
				<script>
					/*
						이벤트 핵심내용 3/4 
							- 이벤트 발생 시키기
							- 핵심 메서드 및 프로퍼티 
								- 이벤트 생성 : Document.createEvent()
								- 이벤트 발생 : HTMLElement. dispatchEvent( )
					 */
					window.onload=function(){
						
						/*
							미션 1 : 
								- btn_1이 클릭되는 경우 btn_2가 클릭된 것처럼 
								   click이벤트를 동적으로 발생시켜 주세요.
						 */
						var btn_1 = window.document.getElementById("btn_1");
						var btn_2 = window.document.getElementById("btn_2");
						
						btn_1.addEventListener("click",function(e){
							//1.이벤트 생성.
							var mouseEvent = document.createEvent("MouseEvent");
							//2.  이벤트 객체에 이벤트와 함께 실어서 보낼 데이터 추가.
							mouseEvent.clientX = 100;
							mouseEvent.clientY = 100;
							//3. 이벤트 초기화.
							mouseEvent.initEvent("click",false,false);
							//4.이벤트 발생.
							btn_2.dispatchEvent(mouseEvent);
						});
						
						btn_2.addEventListener("click",function(e){
							alert("click이벤트 발생 , target = "+e.target.id+", clientX = "+e.clientX+", clientY = "+e.clientY);
						});
					}
				</script>
			</head>

			<body>
				<div> 버튼1이 눌렸는데 버튼2의 click 이벤트가 발생합니다. 신기하죠? </div>
				<

사용자 정의 이벤트 만들기

사용자 정의 이벤트를 제작하는 방법은 다음과 같은 순서로 작성을 한다.
  1. 1. 먼저 사용자정의 이벤트를 나타내고자 document의 createEvent()의 매개변수 값에 'Event'를 전달한다.
  2. 2. 이벤트와 함께 담아서 보낼 데이터를 이벤트 객체에 추가한다.
  3. 3. 이벤트 초기화를 위해 initEvent()를 호출시 첫번째 매개변수 값에 발생시킬 이벤트 타입의 이름을 지정한다.
  4. 4. 생성한 이벤트 객체를 dispatchEvent()의 매개변수 값으로 전달해서 실행한다.
			<html>
			<head>
				<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
				<title></title>
				<script>
					/*
						이벤트 핵심내용 4/4 
							- 사용자 정의 이벤트 만든 후 발생시키기.
							- 핵심 메서드 및 프로퍼티 
								- 이벤트 생성 : Document.createEvent()
								- 이벤트 발생 : HTMLElement. dispatchEvent( )
					 */
					window.onload=function(){
						/*
							미션 1 : 
								- btn_1이 클릭되는 경우 사용자 정의 이벤트인 myEvent를
								  만든 후 data1="이 정보를 이벤트에 담아서 보낻주세요."라는
								  데이터를 실어서 발생시켜 주세요.
						 */
						var btn_1 = window.document.getElementById("btn_1");
						btn_1.addEventListener("click",function(e){
							//1.이벤트 생성.
							var myEvent = document.createEvent("Event");
							//2.  이벤트 객체에 이벤트와 함께 실어서 보낼 데이터 추가.
							myEvent.data1 = "이 정보를 이벤트에 담아서 보내주세요.";
							//3. 이벤트 초기화.
							myEvent.initEvent("myEvent",false,false);
							//4.이벤트 발생.
							btn_1.dispatchEvent(myEvent);
						});
						
						btn_1.addEventListener("myEvent",function(e){
							alert("myEvent 이벤트 발생 , target = "+e.target.id+", data1 = "+e.data1);
						});
					}
				</script>
			</head>

			<body>
				<div> 버튼1이 클릭되면 커스텀 이벤트인 myEvent가 발생합니다. </div>
				<button id="btn_1">버튼1</button>        
				
			</body>
			</html>
		

위치 및 크기와 관련된 프로퍼티와 메서드


HTML Element 객체에서 제공하는 크기 및 위치 관련 프로퍼티와 메서드

HTMLElement 객체는 객체 가운데 위치 및 크기와 관련된 프로퍼티와 메서드를 가장 많이 포함한 객체이며, 브라우저 화면에 보이는 대부분의 객체는 HTMLElement 객체를 상속받았기 때문에 동적으로 요소를 움직여야 하는 경우 대부분 이 객체의 프로퍼티와 메서드를 사용한다.

1) element.offsetWidth , element.offsetHeight
엘리먼트의 너비와 높이 (단, margin제외 / border,padding,scrollbar 포함)
2) element.offsetLeft , element.offsetTop
컨테이너(offsetParent)를 기준으로 엘리먼트가 위치한 x,y 좌표
3) element.scrollWidth , element.scrollHeight
엘리먼트의 너비와 높이 (단, overflow:scroll인 경우 화면에 보이지 않는 영역까지 포함됨)
4) element.scrollLeft , element.scrollTop
스크롤된 x,y 좌표
5) element.clientWidth , element.clientHeight
엘리먼트 내부의 클라이언트 영역의 너비와 높이 (다시말해 엘리먼트의 border,padding,scrollBar를 뺀 안쪽 너비와 높이)
6) element.clientLeft , element.clientTop
엘리먼트 내부에서 클라이언트가 위치한 x,y 좌표, border값과 같음.

미션


미션-1

숫자는 1부터 시작해 0.02초마다 1씩 증가하며 이 숫자 정보를 <span>1</span>처럼 <span> 태그에 넣는다. 이렇게 생성된 <span> 태그를 #panel에 자식 노드로 계속 추가하며 폰트 크기는 10px~50px 사이로, 글자색은 무작위로 출력한다.

			var nCount = 0;
			var panel = null;

			window.onload=function(){
			
				this.init();	//초기화
				this.start();	//타이머 시작

			};

			//초기화
			function init(){
				this.panel = document.getElementById('panel');
			}

			//타이머 시작
			function start(){
				//0.02초마다 addTag() 함수를 실행하는 타이머를 실행한다.
				setInterval(this.addTag, 20);
			}

			//새로운 span 요소 생성
			function addTag(){
				nCount++;
				if(nCount>62) return false;

				var span = document.createElement('span');

				//글자 크기와 글자 색을 무작위로 설정한다.
				span.style.color = '#'+(parseInt(Math.random()*0xffffff)).toString(16);
				span.style.fontSize = (10+parseInt(Math.random()*40))+'px';

				//<span> 태그의 display 방식을 inline-block으로 만들어 panel에 <span> 태그가 추가될 때 자동으로 줄바꿈되게 한다.
				span.style.display = 'inline-block';

				//숫자를 span의 내부 텍스트 값으로 설정한다.
				span.innerHTML = this.nCount;

				//신규로 생성한 <span>태그를 부모 노드에 추가한다.
				this.panel.appendChild(span);

				//추가되는 내용을 확인하기 위해 스크롤한다.
				this.window.scrollTo(0, window.document.body.scrollHeight);
			}