2009.09.11 09:12

jQuery Selector 를 이해해 보자.

강력한 jQuery Selector. 
javascript 의 원래 문법에 비해 너무도 강력한 css style 의 selecting 을 지원한다. 
하지만 css 엔진을 이용하는 것이 아니고, 
원래의 javascript 접근방식으로 재해석하여 동작하는 것이므로, 
jQuery 가 어떻게 selecting 해 올지 예상하는것이 필요하다. 
그렇지 않으면 모든 dom 객체를 수십번 훑는 막장 코드가 나올지도 모른다. 

일단 js 에서 dom 객체를 선택하는 방법을 생각해 보자. 

document.name 
getElementById() 
getElementsByName() 
getElementsByTagName() 
getElementsByClassName() 

getElementsByClassName() 의 경우 최신의 몇몇 브라우저에서만 지원된다. 

때문에, $('.class') 로 selecting 한다면 
대부분의 브라우저에서는 getElementsByTagName('*') 을 실행하고야 말 것이다. 

getElementsByTagName() 의 경우 document 만이 아니고, 
모든 dom 객체에 정의되어 있다는 점도 중요하다. 

또 중요한 것은 getElementsByAttribute() 라는 것은 없다는 것이다. 


/* hasClass() 는 className 이 맞는지 검사하는 임의의 함수라 생각하자. 
== 로는 안되므로 조금 복잡한 비교가 필요하다. */ 

1) 목표물이 모여있다면, 상위 block 에 id 를 주고 $('#yourblock .class') 로 접근한다. 
예상) var yourblock = document.getElementById('yourblock'); 
var tags = yourblock.getElementsByTagName('*'); 
var classes = []; 
for(i = 0; i < tags.length; i ++) { 
if(hasClass(tags.className, 'class')) classes.push(tags[i]); 

- 아직 많이 복잡해 보인다. 

2) 한 종류의 태그라면 태그명을 표기해 주는것이 좋다. $('#yourblock a.class') 
예상) var yourblock = document.getElementById('yourblock'); 
var tags = yourblock.getElementsByTagName('A'); 
var classes = []; 
for(i = 0; i < tags.length; i ++) { 
if(hasClass(tags[i].className, 'class')) classes.push(tags[i]); 

- 별 차이가 없지만 * 이 A 가 되어 많이 줄어들었다. 

3) 여기저기 흩어져 있다면, 차라리 name 을 줄 수 있는 a 태그 같은것을 이용한다. 
getElementsByName() 은 모든 브라우저에 있고, 
href 속성을 주지 않으면 a 로써의 특징적인 link 로써의 기능이 활성되지 않으므로 쓸만하다. 
$('a[name=class]') 
예상) var names = document.getElementsByName('class'); 
var aclass = []; 
for(i = 0; i < names.length; i ++) { 
if(names[i].tagName == 'A') aclass.push(names[i]); 


4) 찾고자 하는것이 하나이면 더 이상 찾지 않도록 수량을 지정해 준다. 
$('#id div.block:first a:first') 
$('#id ul.block > li') #ul li ul li 같은 다중 ul li 처럼 깊은곳의 li 를 제외하기 위해 .class 를 주는 것 보다는 > 지시자로 깊이를 확정해 버리는 것이 좋다. 
/* MySQL 도 unique 한 자료를 select 할 때에 limit 1 을 주면 더 빠르다. */ 

5) 굳이 jQuery 가 필요하지 않은 경우를 구분한다. 
form id="frm" onsubmit="return ajaXing(this);" 
function ajaXing(frm) { 
이라면, 
frm.name.value 로 접근이 되므로, 굳이 jQuery 로 다시 selecting 할 필요가 없다. 
$() 에는 select query 만이 아니고, dom 객체도 직접 넣을 수 있으므로, 
$(frm.name) 으로 이용할 수도 있다. 



-- 상위의 this 접근 
$('#id').each(function() { 
$('input[name="chk[]"], this).each(function() { 

#id 가 form 이라면 여기서 그냥 this.form 으로 접근하면 될 것이다. 
하지만 form 이 아니라면 상위의 this 로 접근하기가 곤란하다. 

$('#id').each(function() { 
var $$ = this; 
$('input[name="chk[]"], this).each(function() { 

이제 상위의 this 는 $$ 로 접근할 수 있게 되었다. 



-- var obj = $('#id'); 
jQuery 객체를 변수에 담아두면, 
selecting 을 다시 하지 않으므로 재사용시 속도에 이득이 있다. 
하지만, dom 객체를 감싸버렸기 때문에 원래 객체로의 접근성이 떨어지게 된다. 
var obj = document.getElementById('test'); 
obj.testArr = document.getElementsByName('test'); 
라고 할 때 
$(obj) 에서 testArr 를 직접 접근할 방법이 없다. 
$(obj).each(function() { 
this.testArr 
이렇게 해야 한다. 
때문에, 상황에 따라 적절한 선택이 필요하다. 



License : Public Domain


신고
Trackback 0 Comment 1
  1. BlogIcon LazyGyu 2009.09.21 10:27 신고 address edit & del reply

    $(obj).each(function(){ this }); 의 this 를 참조하려면

    $(obj)[0] 으로 가능합니다~



티스토리 툴바