DOM Interface
Javascript 2012. 3. 24. 15:00
IE를 제외한 대부분의 표준 브라우저(파폭, 사파리, 크롬, 오페라)에서는 HTMLElement 라는 인터페이스가 존재합니다.
- 여기서 인터페이스란?
간단히 말해 개발자 언어(java, javascript)와 DOM 의 의사소통을 담당하는 중간 매개체로 볼 수 있습니다.
"개발자는 DOM 내부 구현에 대한 지식 없이 다양한 언어(java, javascript, ect)를 통해 객체와 인터페이스로 문서에 접근 할 수 있습니다.
즉, 자바스크립트를 통해 생성된 엘리먼트는 고유의 인터페이스를 제공받게 되는 것입니다."
즉, 자바스크립트를 통해 생성된 엘리먼트는 고유의 인터페이스를 제공받게 되는 것입니다."
아래는 위에서 설명드린 부분을 보여주는 소스코드 입니다.
그 하위 인터페이스인 HTMLELement 는 Elemenet 인터페이스를 상속받아 구현되고 그 아래는 문서의 모든 엘리먼트들이
존재합니다.
또한, 아래 그림은 DOM 탐색 시 쓰이는 함수 목록이며, 노란색 부분은 그중에서도 자주 쓰이는 함수를 나타낸 것입니다.
그럼 이제부터 HTMLElement 인터페이스를 활용하여 문서의 모든 엘리먼트에 객체 맴버를 추가 시킬 수 있는 방법에 대해
알아보도록 하겠습니다.
- HTML 소스
- 공통 함수
아래는 HTMLElement 인터페이스를 지원하는 표준 브라우저 방식의 코드입니다.
위에서 언급한 바와 같이 IE 브라우저는 HTMLElement 객체를 제공하지 않습니다.
하지만 IE 브라우저 에서도 아래와 같이 유사 기능을 구현할 수 있습니다.
아래 코드는 이전에 구현되지 않았던 함수 체인방식이 적용된 코드입니다.
지금까지 문서의 모든 엘리먼트에 객체 맴버를 추가 시킬 수 있는 방법에 대해 알아보았습니다. 하지만 이 방법은 실무에서 거의 사용되지 않는 것이 사실입니다.
즉, DOM 인터페이스를 학습하기 위한 코드이며, 더 많은 학습을 원하고 실무에서 사용 가능한 코드를 작성하고 싶다면 cssQuery 나 jQuery 의 내부 로직 중 DOM 탐색에 대한 부분을 분석하는 것을 추천합니다.
참고 사이트:
DOM Interface in javascript- @Rhio.Kim's blog http://rhio.tistory.com/198
-
if (HTMLElement)
-
{
-
// 각 엘리먼트들은 object를 취하며, 고유의 인터페이스를 제공받습니다.
-
-
alert(document.createElement('div')); // object HTMLDivElement && HTMLDivElement interface
-
alert(document.createElement('img')); // object HTMLImageElement && HTMLImageElement interface
-
alert(document.createElement('input')); // object HTMLInputElement && HTMLInputElement interface
-
}
아래 DOM Interface를 나타내는 그림에서처럼 DOM에 접근하기 위한 가장 상위 인터페이스는 Document이며,
존재합니다.
또한, 아래 그림은 DOM 탐색 시 쓰이는 함수 목록이며, 노란색 부분은 그중에서도 자주 쓰이는 함수를 나타낸 것입니다.
그럼 이제부터 HTMLElement 인터페이스를 활용하여 문서의 모든 엘리먼트에 객체 맴버를 추가 시킬 수 있는 방법에 대해
알아보도록 하겠습니다.
- HTML 소스
- 공통 함수
-
// 객체 상속 함수
-
function extend(){
-
-
var target = this
-
, opts = []
-
, src = null
-
, copy = null;
-
-
for (var i = 0, length = arguments.length; i < length; i++) {
-
-
opts = arguments[i];
-
-
for (var n in opts) {
-
src = target[n];
-
copy = opts[n];
-
-
if (src === copy) continue;
-
if (copy) target[n] = copy;
-
}
-
}
-
}
-
-
-
// 각 맴버가 추가 되어있는 객체
-
var nodes =
-
{
-
prev: function(){
-
-
elem = this;
-
-
do{
-
elem = elem.previousSibling;
-
}
-
while(elem && elem.nodeType !== 1)
-
-
return elem;
-
},
-
-
next: function(){
-
-
elem = this;
-
-
do{
-
elem = elem.nextSibling;
-
}
-
while(elem && elem.nodeType !== 1)
-
-
return elem;
-
}
-
}
아래는 HTMLElement 인터페이스를 지원하는 표준 브라우저 방식의 코드입니다.
-
// 표준 브라우저 방식
-
// HTMLElement 하위의 모든 엘리먼트에 nodes객체의 모든 맴버를 추가 시킵니다.
-
if (window.HTMLElement){
-
-
extend.call(window.HTMLElement.prototype, nodes);
-
-
alert(document.getElementById('test3').prev().prev().next().id); // test2
-
-
}
위에서 언급한 바와 같이 IE 브라우저는 HTMLElement 객체를 제공하지 않습니다.
하지만 IE 브라우저 에서도 아래와 같이 유사 기능을 구현할 수 있습니다.
-
// 비표준 브라우저 방식
-
if (!window.HTMLELement){
-
-
var fnCreate = document.createElement
-
, fnId = document.getElementById
-
, fnTags = document.getElementsByTagName;
-
-
/*
-
document.createElement = function(tag){
-
var o = fnCreate(tag);
-
o && extend.call(o, nodes);
-
return o || undefined;
-
};
-
-
document.getElementsByTagName = function(tag){
-
var o = fnTags(tag);
-
o && extend.call(o, nodes);
-
return o || undefined;
-
};
-
-
*/
-
-
-
// document 객체의 맴버함수를 오버라이하여 구현합니다.
-
document.getElementById = function(id){
-
var o = fnId(id);
-
o && extend.call(o, nodes);
-
return o || undefined;
-
};
-
-
alert(document.getElementById('test2').prev().id); // test1
-
alert(document.getElementById('test1').next().id); // test2
-
-
}
아래 코드는 이전에 구현되지 않았던 함수 체인방식이 적용된 코드입니다.
-
var nodes =
-
{
-
prev: function(){
-
-
elem = this[0] || this;
-
-
do{
-
elem = elem.previousSibling;
-
}
-
while(elem && elem.nodeType !== 1)
-
-
this[0] = elem;
-
-
// 이전 코드처럼 elem를 반환하지 않고 getElementById 함수 호출시 nodes객체의 모든 맴버가 추가 되어있는 'test2' 객체를 반환하여 체인방식을 적용시킵니다.
-
-
return this;
-
},
-
-
next: function(){
-
-
elem = this[0] || this;
-
-
do{
-
elem = elem.nextSibling;
-
}
-
while(elem && elem.nodeType !== 1)
-
-
this[0] = elem;
-
-
return this;
-
}
-
}
-
-
if (!window.HTMLELement){
-
var fnCreate = document.createElement
-
, fnId = document.getElementById
-
, fnTags = document.getElementsByTagName;
-
-
/*
-
document.createElement = function(tag){
-
var o = fnCreate(tag);
-
o && extend.call(o, nodes);
-
return o || undefined;
-
};
-
-
document.getElementsByTagName = function(tag){
-
var o = fnTags(tag);
-
o && extend.call(o, nodes);
-
return o || undefined;
-
};
-
-
*/
-
-
document.getElementById = function(id){
-
var o = fnId(id);
-
o && extend.call(o, nodes);
-
return o || undefined;
-
};
-
-
alert(document.getElementById('test2').prev().next()[0].id); // test2
-
-
}
지금까지 문서의 모든 엘리먼트에 객체 맴버를 추가 시킬 수 있는 방법에 대해 알아보았습니다. 하지만 이 방법은 실무에서 거의 사용되지 않는 것이 사실입니다.
즉, DOM 인터페이스를 학습하기 위한 코드이며, 더 많은 학습을 원하고 실무에서 사용 가능한 코드를 작성하고 싶다면 cssQuery 나 jQuery 의 내부 로직 중 DOM 탐색에 대한 부분을 분석하는 것을 추천합니다.
참고 사이트:
DOM Interface in javascript- @Rhio.Kim's blog http://rhio.tistory.com/198