소프트웨어/JavaScript • Dhtml

jQuery Selector 를 이해해 보자.

falconer 2009. 8. 6. 08:59
강력한 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[]"]).each(function() {

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

$('#id').each(function() {
var $$ = this;
$('input[name="chk[]"]).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
이렇게 해야 한다.
때문에, 상황에 따라 적절한 선택이 필요하다.



출처 : http://phpschool.com/gnuboard4/bbs/board.php?bo_table=tipntech&wr_id=69008&page=1