jQuery : 조작(Manipulation) 메서드

필자의 잡담~

뭐냐! 설마 이 강좌를 책으로 제작하자는 제의라도 들어온 것이냐? 너무 강좌가 안 올라와서 그런 줄 알았다. 역시 그런 불순한 의도로 강좌를 쓴 것이구나! 하시는 분들이 혹시 계시지는 않겠죠? 다만, 그냥 바빴을 뿐입니다.ㅎㅎ (책을 쓸 의향도 없어요!)

게다가, 첫 강좌에서도 말씀드렸지만, 이 jQuery 강좌는 2-3회 정도로 정리해서 초반 길잡이만 하려 했던 것인데요. 어쩌다보니, 현재 너무 장황해진 거 같아서 살짝 부담도 되고 있긴 합니다. 어쩌면 기쁜 부담이죠~

그래도, 주욱 해온대로 원하는 내용을 원하는 시간에 쓰고자 합니다. 그래야 읽을만한 글이 될거라 생각하니까요. 강좌 처음에도 말씀드렸다시피, 더 많은 내용이 필요하신 분은 책! 마음의 양식을 잊지 마세요

이번 강좌에서는 이전에 언급한대로 jQuery의 조작(Manipulation) 관련 메서드들에 대해서 다루어 볼까 합니다. 사실, 이미 기초를 뗀 여러분들에게 조작관련 메서드, 탐색관련 메서드를 굳이 구분지어서 설명할 필요는 없다는 느낌도 들긴 하지만 그래도 깔끔한 정리를 위해서 말이죠 ^^;

조작 관련 메서드라 함은 요소에 값을 지정한다거나, 특정 요소의 값을 읽어온다거나 하는 작업을 포함해서, 동적으로 요소 자체를 생성, 삭제, 복사, 제거하는 기능들을 의미합니다. 전체 목록은 jQuery 공식 페이지인 http://docs.jquery.com/Manipulation 에서 확인하실 수 있고요. 저는 그러한 메서드들 중에서 자주 사용될만한 것들 위주로 설명을 할까 합니다.

우선, 현재 jQuery에서 제공하는 조작과 관련한 메서드들은 크게 7개의 카테고리로 나누어져 있는데요. 그들은 각각 요소의 내용을 조작하는 메서드, 요소를 추가하거나 삭제하는 메서드, 요소를 래핑하거나 바꿔치기 하는 메서드, 요소를 제거하거나 복사하는 메서드들로 구분되어 있습니다. jQuery의 버전이 올라가면 이러한 카테고리는 더 추가되거나 정리될 수도 있습니다만, 현재의 버전은 이러한 카테고리를 가지고 있기에, 강좌도 그에 따라 설명하겠습니다(다만, 전체 카테고리를 다 설명드리지는 못할 듯 하고요. 제가 상대적으로 자주썼던 5개의 카테고리만을 설명할 예정입니다).

jQuery의 조작 메서드 중 하나의 카테고리인 요소의 내용을 다루는 메소드로는 다음과 같은 것들이 있습니다.

내용 변경 메서드
html() 일치된 요소의 html 내용을 가져옵니다. 이는 요소의 innerHTML 값과 동일합니다. 만일, 일치된 요소가 여러 개라면 그 중 첫 번째 요소의 HTML을 가져옵니다.
html(val) 일치된 요소의 html 본문을 val 값으로 설정합니다. 만일, 일치된 요소가 여러 개라면 모든 요소에 이러한 작업을 수행합니다
text() 일치된 모든 요소의 텍스트를 합쳐서 가져옵니다.
text(val) 모든 일치된 요소의 텍스트를 val 값으로 설정합니다.

사실, 이 메서드들은 이전 강좌에서도 만나보았던 것인데요. 그 때 제가 다음과 같이 설명을 드렸을 겁니다.

'text() 메서드는 해당 개체가 가지고 있는 컨텐트를 텍스트로 반환하는 메서드입니다. 이와 유사한 메서드로는 html()이 있는데요. 이는 개체가 포함하고 있는 html 컨텐트를 반환하는 메서드입니다. 이 메서드들은 인자를 사용하지 않으면 값을 가져오는 역할을 하지만, 인자로 값을 지정하면 그 값으로 원래의 값을 바꾸는 역할을 합니다.

text() 메서드의 재미있는 점은 개체의 컨텐트가 html 요소들을 포함하고 있다고 해도, 다 무시하고 텍스트만을 반환한다는 점입니다. 즉, <span><b>taeyo</b></span> 와 같은 span 개체가 있을 때, 이 span 개체에 대해서 text()를 수행하면, 반환값은 내부 html을 제외한 "taeyo"가 되고요. html() 메서드를 사용하면 <b>taeyo</b>를 반환한다는 것이죠.'

사실, 위의 설명이면 이 메서드들을 이해하는데 충분할 것이라 생각하지만, 기왕 말을 꺼낸 김에, 약간의 설명을 덧붙일 것이 있습니다. 이는 jQuery로 검색된 대상 요소가 여러 개일 경우, text() 메서드와 html() 메서드의 동작이 약간 다르다는 것인데요. 일치된 요소가 여러 개인 경우, text() 메서드는 일치된 모든 대상의 텍스트를 결합해서 반환하는 반면, html() 메서드는 일치된 요소들 중 첫 번째 요소의 html 만을 반환한다는 것이 그 차이이지요. 크게 중요한 사항은 아니지만, 이 차이를 모르면 jQuery를 사용하다가 간혹 결과가 이상하게 나온다고 불만을 가질 수 있으므로 기억 해 두시기 바랍니다.

이어지는 메서드들은 특정 요소나 개체 집합을 다른 요소의 "내부"에다가 앞, 뒤로 덧붙이는 기능을 제공하는 메서드들입니다.

추가(요소 내부에) 관련 메서드
append(content) 일치된 요소의 내부에 content를 덧붙입니다.
appendTo(selector) 일치된 요소를 selector에 의해 일치된 모든 요소들 내부에 덧붙입니다. 만일, 일치된 요소가 본문에 존재하는 개체(예, $("#some")과 같은)라면 그를 제거한 후 복사(즉, 이동)합니다. 설명이 어려우면 밑의 예제를 참고하세요.
prepend(content) append(content)와 동일하며, 다만, 내부 앞쪽에 붙여 넣습니다.
prependTo(selector) appendTo(selector)와 동일하며, 다만, 내부 앞쪽에 붙여 넣습니다.

append(content) 메서드는 이름이 의미하는 바가 명확하기에, 쉽게 이해할 수 있을 것입니다. 인자로 지정된 content를 jQuery 개체 내부에 덧붙이는 것이니까요. 예를 들어, 다음과 같은 표현이 있다고 가정해 봐요.

$("b.link").append("(클릭)");

이는 link라는 css 클래스를 갖는 B 태그 내부에 "(클릭)" 이라는 문자열을 추가하는 예입니다. B 태그 내부 뒤쪽에 덧붙이는 것이기에 "(클릭)"이라는 단어도 당연히 굵게 표현될 것입니다. 즉, 다음과 같은 최종 html이 형성된다는 것이죠.

<b class="link">굵은 글자임 (클릭)</b>

참 쉽죠? 하지만, 혹시 순간적으로 이렇게 간단한 메서드가 왜 필요할까라는 생각을 하지는 않으셨나요? 아니라고요? 글쎄요. 순간! 하신 것 같은데.. -_-+. 하셨던 안 하셨던은 사실 중요하지 않습니다. 이미 개그로 꺼낸 말이 지루해져 버렸으니까요(엉엉). 어쨌든, 이 메서드는 상당히 유용하게 사용되곤 합니다. 예를 들어, 저처럼 강좌를 Html로 길게 쓴 다음, 주석을 표현하고자 할 경우에 말이죠. 주석 표시를 HTML로 표현하는 경우에는 <sup>라는 태그를 사용하곤 하는데요. 그것을 수동으로 일일이 태그를 달자면 상당히 노가다스럽습니다. 주석 태그를 수십개 달아뒀는데, 순서라도 바뀌는 날에는 생각만해도 피곤해 집니다. 하지만, 주석을 표현해야 할 단어들에 대해서 .annotation이라는 스타일 클래스를 지정해 두었다면(대부분 스타일을 지정하죠), 다음과 같은 jQuery 구문을 통해서 주석표시를 일괄적으로 해결할 수 있습니다.

$(".annotation").each(function(i) {
  
var idx i + 1;
  
$(this).append("<sup>" + idx + "</sup>");
});

이는 .annotation라는 css 클래스가 지정된 html 요소들에 대해서 <sup>1</sup>, <sup>2</sup>와 같은 주석 표현 태그를 동적으로 덧붙여주는 코드입니다. 일일이 단어의 뒷 부분에 <sup>1</sup>와 같은 태그를 수동으로 추가할 필요없이, jQuery를 이용해서 동적으로 그러한 표현을 추가할 수 있는 아주 유용한 예라고 볼 수 있습니다. 이제 jQuery님 좀 짱으로 보이시지 않나요? 다음 그림은 그렇게 처리한 예를 보여줍니다.

append(content) 메서드가 간단하면서도 유용하기에, 그와 유사한 appendTo(selector) 메서드도 관심을 가져 볼만 합니다. 그런데, 이 메서드는 사용법이 상대적으로 살짝 복잡하게 느껴질 수 있습니다. append와는 덧붙이기의 대상이 반대이며, 더불어, 셀렉터에 의해 일치된 대상 모두에게 덧붙여지기 때문이지요. 다음 예를 한번 볼까요?

$("#linkText").appendTo("a.link");

이는 #linkText 라는 아이디를 갖는 요소를 얻어서, 그를 link라는 css 클래스를 갖는 "모든" 하이퍼링크 뒤에 덧붙이게 됩니다. 그러면서, 원래의 #linkText 요소는 사라집니다. 원본 개체는 복사되면서 제거되는 것이죠. 더불어, 다음과 같은 구문도 가능합니다.

$("<font>(클릭)</font>").appendTo("b");

이는 <font>(클릭)</font>라는 태그 문자열을 동적으로 생성한 뒤, 그를 모든 B 태그의 뒤에 덧붙이는 역할을 합니다. 어때요? appendTo 메서드가 어떤 역할을 하는지 이해가 되시죠?

말이 나온 김에, 우리는 $()라는 핵심 표현에 대해 살펴보고 넘어가야 할 필요성이 있습니다. 가장 기본적이면서 가장 마법스러운 $()라는 특이한 표현이 제공하는 다양한 기능을 말이죠.

여러분은 $() 표현이 jQuery()라는 구문의 단축표현이자, 셀렉터를 수행하기 위한 구문이라고 알고 있을 것입니다만, 실은 그 외에도 3가지의 기능을 더 가지고 있습니다.

자세한 내용은 http://docs.jquery.com/Core 를 보면 잘 나와있습니다만, 간략하게 설명을 드리면 각 기능은 이렇습니다.

1. 인자로 셀렉터를 지정한 경우에는 일치되는 모든 요소를 찾는다.
2. 인자로 html 태그를 지정한 경우에는 동적으로 그 요소를 생성한다.
3. 인자로 특정 DOM 요소를 지정하면, 그 요소의 jQuery 래퍼를 생성한다.
4. 인자로 function을 지정하면, 그는 $(document).ready() 메서드와 동일하다.

간단하죠?

해서, $("<font>(클릭)</font>") 라는 표현은 동적으로 font 요소를 생성하게 되는 것이고요. $("#linkText")라는 표현은 #linkText라는 셀렉터에 일치하는 요소들을 검색하게 되는 것이죠.

append와 appendTo 메서드를 이해하셨으면, prepend와 prependTo 메서드도 쉽게 이해하실 수 있을 것입니다. 영어사전에서 이 단어들을 검색하지는 마세요. 이런 단어는 공식적으로는 존재하지 않으니까요. 단지, pre-append 라는 의미라고 생각하시면 됩니다. 즉, prepend는 append와 동일하지만, 요소를 뒤에 덧붙이는 것이 아니라 앞에 덧붙인다는 차이가 있습니다. prependTo도 마찬가지고요. 하하. 설명 안해줘도 그럴 것인줄 이미 알았다고 말씀하실 줄 저도 알았습니다.

세번째 메서드 그룹은 위의 추가(내부) 관련 메서드와 유사하긴 하지만, 요소 내부에 추가를 하는 것이 아니라, 요소 외부에 추가하는 메서드 그룹입니다.

추가(요소 외부에) 관련 메서드
after(content) 일치된 요소 뒤에 content를 삽입합니다. 요소 내부가 아닌 외부에 삽입된다는 것을 제외하면 append와 동일합니다.
before(content) 일치된 요소 앞에 content를 삽입합니다. 요소 내부가 아닌 외부에 삽입된다는 것을 제외하면 prepend와 동일합니다.
insertAfter(selector) 일치된 요소를 selector에 의해 일치된 모든 요소들 뒤쪽에 삽입합니다. 요소 내부가 아닌 외부에 삽입된다는 것을 제외하면 appendTo와 동일합니다.
insertBefore(selector) insertBefore(selector)와 유사하나, 요소 앞쪽에 삽입합니다. 요소 내부가 아닌 외부에 삽입된다는 것을 제외하면 prependTo와 동일합니다.

after 메서드는 앞서 설명한 append 메서드와 눈에 보이는 결과는 유사합니다. 다만, 태그 내부에 덧붙이는 것이 아니라, 태그 바깥쪽에 덧붙인다는 차이가 있지요. 예를 들어, 다음 구문을 보도록 해요.

$("a").after("<font>(클릭)</font>");

이는 모든 하이퍼링크 바로 뒤에 "<font>(클릭)</font>" 이라는 태그 문자열을 덧붙이는 구문입니다. 해서, 결과로 다음과 같은 태그가 구성되는 것이죠.

<a href="http://taeyo.net">태오 사이트</a><font>(클릭)</font>

만일, after 메서드 대신 append 구문을 다음과 같이 사용했다면,

$("a").append("<font>(클릭)</font>");

이는 다음과 같은 결과 태그를 구성했을 것입니다.

<a href="http://taeyo.net">태오 사이트<font>(클릭)</font></a> 

차이가 느껴지시죠?

같은 방식으로 before 메서드도 prepend 메서드와 유사합니다. 태그 내부에 삽입 되느냐 외부에 삽입되느냐만 차이가 있는 것이죠. 마찬가지로, insertAfter()는 appendTo() 메서드와 동일하게 동작하며, insertBefore()는 prependTo()와 동일하게 동작합니다. 다만, 자식 요소로서 태그 내부에 삽입되느냐, 형제 요소로서 외부에 삽입되느냐의 차이만 있다는 것이죠. 참 쉽죠?

스피디하게, 이어지는 소개할 메서드 그룹은 삭제용 메서드와 복사용 메서드들입니다.

삭제 메서드
empty() 모든 일치된 요소들의 자식 노드들을 제거합니다.
remove() 모든 일치된 요소들을 DOM에서 제거합니다.
복사 메서드
clone() 일치된 요소를 복사하고, 그를 선택합니다.
clone(bool) 이벤트 처리기를 포함하여 DOM 요소를 복사하고 그를 선택합니다.

별도의 설명이 필요없을 정도로 직관적이면서도, 매우 자주 사용하게 되는 메서드들입니다. 다만, 복사 관련 메서드(clone)는 약간의 부연 설명을 드릴 필요가 있는데요. 인자로서 true를 지정하게 되면, 단순히 요소만을 복사하는 것이 아니라, 그 요소에 달려있는 이벤트 처리기(예, click, mouseover)등도 복사가 된다는 것입니다. 인자가 없는 기본 clone() 메서드로 복사하게 되면, 요소 자체만 복사될 뿐, 해당 요소에 달려있는 이벤트 처리기들은 복사가 되지 않습니다. 해서, 이벤트 처리기까지 복사하고 싶다면 반드시 clone(true) 메서드를 사용해서 대상을 복사해야 한다는 점에 주의하세요.

자. 그럼, 이번 강좌에서 설명한 메서드들을 전반적으로 확인해보는 종합 예제를 같이 해 볼까요? 다음과 같은 htm 페이지를 하나 작성해 보도록 해요.

Manip.htm

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
  
<title></title>
  
<script src="jquery-1.3.2.min.js" type="text/javascript"></script>
  
<script type="text/javascript">
    $(
document).ready(
      
function() {
        $(
".annotation").each(function(i) {
            
var idx i + 1;
            
$(this).after("<sup>" + idx + "</sup>");
        
});

        
$("button").click(function() {
            
alert($(this).val());
            
$(this).remove();
        
});

        var 
$prev $("#prevBtn").clone();
        var 
$next $("#nextBtn").clone(true);

        
$("div#bottomDiv").prepend($prev);
        
$("div#bottomDiv").append($next);
    
});
  </
script>
  
<style type="text/css">
    
* { font-size:12px; font-family:돋움; }
    
.annotation { background: pink; }
  </
style>
</head>
<body>
  
<button id="prevBtn">이전 페이지로</button>
  
<button id="nextBtn">다음 페이지로</button>
  
<h3>jQuery란?</h3>
  
<div>
    
<b>jQuery</b>는 가볍고 빠르며, 간결한 <font class="annotation">오픈소스</font> 스크립트 라이브러리입니다. 이를 이용하면 Rich 웹 UI를 개발하는 데 도움이 되는 다양한 기능들 즉, HTML 문서  <font class="annotation">트래버스</font>, 이벤트 처리, 애니메이션, <font class="annotation">Ajax</font> 상호 작용 등을 지원하여 빠르고 견고하게 리치 웹 애플리케이션 개발을 할 수 있도록 지원합니다.
  
</div>
  
<br />
  <
div id="bottomDiv"></div>
</body>
</html>

jQuery 코드는 주석 표현을 화면에 삽입하는 것으로 시작하고 있습니다. append() 메서드를 설명할 때 예시했던 소스를 사용해서 말이죠. Annotation 이라는 css 클래스를 갖는 요소들을 루프 돌면서 <sup> 태그를 사용하여 주석을 표현하고 있는데요. 앞선 강좌 설명에서는 append 메서드를 사용했던 것에 반해, 이번 예제에서는 after 메서드를 사용해서 주석 표현을 하고 있습니다. 그 편이 좀 더 깔끔해 보여서요.

이어지는 코드는 <button> 요소들에 대해서 click 이벤트 처리기를 달고 있습니다. 그리고, click 처리기에서는 현재 버튼의 텍스트를 메시지박스로 나타낸 뒤, 그 버튼을 DOM에서 제거하도록 remove() 메서드를 사용하고 있습니다.

그리고, 마지막 코드 구역은 이전 페이지 버튼과 다음 페이지 버튼을 복사해서(clone), 하단의 div 영역에 append 하는 것을 볼 수 있습니다. 다만, 이전 페이지 버튼은 clone() 메서드로 복사를 했고, 다음 페이지 버튼은 clone(true) 메서드로 복사를 했기에, 전자는 클릭 이벤트 처리기가 무시되며, 후자는 click 이벤트 처리기까지 포함된 상태로 복사가 된 것을 확인할 수 있을 것입니다. 즉, 복사된 이전 페이지 버튼은 클릭해도 아무런 반응이 없지만, 다음 페이지 버튼은 메시지박스가 뜬다는 것이죠.

이를 테스트한 결과 화면은 다음과 같습니다.

어때요? 참 쉽죠?

jQuery는 참으로 사용하기 쉽고, 직관적인 API들로 구성되어 있다는 것을 느낄 수가 있습니다. 그리고, 개개의 메서드는 간단하지만 그것들을 혼합해서 사용하면 상당히 막강한 기능을 구현할 수 있도록 설계 되어 있죠.

다음 강좌는 트래버스에 관한 강좌를 생각하고 있습니다. 그리고, 그것이 마무리되면 바로 Ajax에 관한 기능들을 설명하는 것으로 일단은 jQuery 강좌를 마무리할 예정에 있어요. 긴 여정이 될지는 모르겠지만 꾸준히 관심을 주시는 분들이 있어서 힘을 더 내보겠습니다.

읽어주셔서 감사합니다.

Ps : 응원이 더 많으면 플러그인 제작까지도… 쿨럭


authored by Taeyo

Posted by 바람이불면
,

jQuery 셀렉터 : 필터 사용하기

필자의 잡담~

제가 jQuery 강좌에서 특히나 셀렉터 부분을 집중적으로 이렇듯 자세하게 설명하는 이유는 현재 출판된 서적이나 아티클들에서 이러한 부분을 조목조목 정리한 문서를 찾아보기가 쉽지 않아서 입니다(물론, 제가 잘 찾지 못했을 수도 있습니다).

더불어, 셀렉터(selector)가 jQuery의 화려한 기능들을 다루기에 앞서 반드시 알아두어야 하는 궁극의 기본기이기에 그렇기도 합니다.
jQuery 셀렉터 : 기본 필터

기본적인 셀렉터에 더하여, jQuery는 다양한 셀렉터 필터들도 제공을 합니다. 바로 앞에서 다루었던 어트리뷰트 셀렉터의 경우도 필터의 한 예입니다만, 어트리뷰트 셀렉터는 지금부터 다룰 필터들과는 표현식이 약간 달라서 기본 셀렉터와 함께 다루었습니다.

필터는 말 그대로 걸러내는 역할을 합니다. jQuery는 위치를 기반으로 필터링 하거나, 하위 자식들을 필터링할 수 있게 한다거나, 컨텐트를 기반으로 필터링하는 등 다양한 방식으로 원하는 요소들을 필터링하여 선택할 수 있게 합니다. 그리고, 대부분의 필터는 : 을 시작문자로 사용하는 단어들입니다. 이러한 필터는 일반적으로 기본 셀렉터에 덧붙여 사용하곤 하지만, 단독으로 사용할 수도 있습니다. 그러면, 우선 가장 일반적인 필터들부터 차례대로 살펴보도록 할까요?

< 기본 필터 >

:first 선택된 개체들 중 첫 번째 요소와 일치합니다.
:last 선택된 개체들 중 마지막 요소와 일치합니다
:not(selector) 괄호에 주어진 셀렉터와 일치되는 모든 요소를 제외합니다.
:even 짝수 요소들과 일치합니다(0부터 시작)
:odd 홀수 요소들과 일치합니다(0부터 시작)
:eq(index) 인덱스에 해당하는 단일 요소와 일치합니다
:gt(index) 주어진 인덱스보다 높은 인덱스를 갖는 모든 요소와 일치합니다
:lt(index) 주어진 인덱스보다 낮은 인덱스를 갖는 모든 요소와 일치합니다
:header 모든 헤더 요소들(h1, h2, h3 등)과 일치합니다
:animated 현재 애니메이션이 동작중인 모든 요소와 일치합니다

각각의 필터는 셀렉터로서 독립적으로 사용될 수도 있고, 다른 셀렉터와 함께 사용할 수도 있습니다. 더불어, 여러 필터를 이어서 사용할 수도 있죠. 예를 들어 다음과 같이 말이죠.

tr:odd
tr:gt(4)
tr:last
:header:eq(1)

각각의 셀렉터가 의미하는 바는 쉽게 이해하실 수 있을 것입니다.

첫 번째 셀렉터인 tr:odd는 현재 문서에 존재하는 모든 tr 중 홀 수번째 열들만을 선택하는 것이며, 두 번째 셀렉터인 tr:gt(4)는 문서에 존재하는 모든 tr 중 그 인덱스가 4 이상인 모든 열들을 선택하는 것이고요. 세 번째 셀렉터인 tr:last는 모든 tr 중 가장 마지막 tr을 선택하는 셀렉터입니다. 그리고, 마지막 셀렉터는 문서에 존재하는 헤더들 중에서 인덱스가 1번째인 헤더를 선택하는 셀렉터이지요.

주의할 점은 여기서의 인덱스는 0부터 시작이라는 것입니다. 고로, 첫번째로 나오는 tr은 인덱스 0을 가지므로, 홀수 열이 아니라 짝수열이라는 것을 기억하셔야 합니다.

해서, 다시 정리하자면,

tr:odd 문서에 나오는 모든 tr 중 홀수번째 tr만을 선택합니다. 그런데, 인덱스는 0부터 시작하므로, 사실, 제일 처음 나오는 tr은 짝수 열로 인식된다는 부분에 주의하세요.
tr:gt(4) 문서에 나오는 tr 중 5번째(인덱스 4) 후에 나오는 모든 tr 즉, 6번째 tr 부터 모든 tr을 선택합니다.
tr:last 문서에 나오는 모든 tr 중 가장 마지막에 존재하는 tr만을 선택합니다.
:header:eq(1) 현재 문서에 나오는 모든 헤더(h1, h2, h3 등) 중에서 인덱스 위치가 1인 헤더 즉, 눈에 보이기에 두 번째로 나오는 헤더를 선택합니다.

필터 앞에 아무것도 지정되지 않으면, 암시적으로 *이 지정된 것으로 인식됩니다. 즉, 이는 *:header:eq(1)와 동일한 표현으로 인식된다는 것이며, 페이지에 존재하는 모든 요소 중에서 헤더를 찾게 됩니다.

라는 것입니다. 하하. 설명이 쉬우니 머리에 쏙쏙 들어오죠? 더욱 이해하기 쉽도록 예제를 통해서 확인을 해보도록 합시다.

Filter01.htm

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    
<title></title>
    
<script src="jquery-1.3.2.min.js" type="text/javascript"></script>
    
<script type="text/javascript">
        $(
document).ready(
            
function() {
                $(
"tr:odd").css("background""#efefef");
                
$("tr:gt(4)").css("background""silver");
                
$("tr:last").css("background""yellow");
                
                
$(":header:eq(0)").css("font-weight""bold").css("color""blue");
            
});
    </
script>
    
<style type="text/css">
        
* { font-size:12px; font-family돋움 }
        
.nameTable { background: white; border-collapse:collapse }
    </
style>
</head>
<body>
    
<h3>수학 시험 점수</h3>
    
<table class="nameTable" border="1" cellpadding="10">
        
<tr><td width="100">name</td><td width="100">value</td></tr>
        
<tr><td>Taeyo</td><td>80</td></tr>
        
<tr><td>Dragon</td><td>98</td></tr>
        
<tr><td>Eric</td><td>85</td></tr>
        
<tr><td>Queeny</td><td>96</td></tr>
        
<tr><td>Youngsun</td><td>88</td></tr>
        
<tr><td>kobukii</td><td>90</td></tr>
        
<tr><td>Mr.Net</td><td>92</td></tr>
    
</table>
</body>
</html>

보시디시피, 문서에는 총 8개의 tr이 존재하고 있고요. 각각의 셀렉터는 그러한 tr을 대상으로 해서 스타일을 매기고 있습니다. css() 라는 메서드는 이전 강좌에서도 다룬 적이 있지만, 대상 개체에 css 스타일을 적용하는 메서드인거 기억하시죠?

예제는 모든 홀수번째 tr(tr:odd)에게는 #efefef 배경색(아주 연한 회색)을 적용하고 있고요. 인덱스 번호 4 이후의 모든 tr들(즉, 6번째 tr 부터)에 대해서는 silver 배경색을 적용하고 있습니다. 그리고, 가장 마지막 tr(tr:last)에 대해서는 yellow 배경색을 주고 있고요. 더불어, 문서상에서 첫 번째로 나오는 헤더(:header:eq(0))에는 굵고 파란색의 폰트를 설정하고 있습니다.

해서, 결과 화면은 다음과 같이 나타나게 되는 것이죠.

매우 간단한 예제였지만, 이 예제는 마지막 셀렉터에 스타일을 주는 부분에서 재미있는 것이 하나 있는데요.

$(":header:eq(0)").css("font-weight""bold").css("color""blue");

라는 구문을 보시면, 셀렉터 대상에 대해서 css()라는 메서드를 연달아 사용하는 것을 볼 수 있죠? 이를 메서드 체인이라고 하는데요. jQuery가 제공하는 모든 메서드는 그 반환값(return value)이 효과가 반영된 jQuery 개체이기 때문에 이런 식으로 메서드를 이어서 사용할 수가 있습니다. 다시 말해서, 저 표현은

var jQ = $(":header:eq(0)")
jQ = jQ.css("font-weight", "bold");
jQ = jQ.css("color", "blue");

와 동일하다 할 수 있다는 것이죠. 하지만, 이러한 방식은 직관적이기는 하지만 소스가 길어지는 단점이 있기에, 일반적으로는 메서드 체인으로 작성하곤 합니다.

물론, 메서드 체인으로 작성할 경우에, 체인이 너무 길어지게 되면 오히려 소스가 더 복잡해 보일 수 있기에 부담스러워 하시는 분들도 있는데요. 자바스크립트는 줄바꿈을 인식하지 않기 때문에 다음과 같이 줄을 바꿔가면서 메서드 체인을 작성할 수 있습니다. 그리고, 대부분의 jQuery 개발자들도 다음과 같은 메서드 체인 방식을 즐겨 사용한답니다.

$(":header:eq(0)")
    .css("font-weight", "bold")
    .css("font-size", "12px")
    .css("color", "blue");

어때요? 보기 편하죠? 지금은 가벼운 예제들이기에 이러한 메서드 체인은 자주 볼일이 없지만, 이후의 강좌에서는 다양한 기능을 다루면서 메서드 체인이 마구 늘어나게 될 것입니다.

위의 메서드 체인에서는 css() 메서드를 3번 연속 사용하고 있는데요. 이는 단지 메서드 체인의 예를 든 것임을 기억하세요. 실제로 저렇게 여러 스타일을 매기고자 하는 경우에는, css 메서드를 반복해서 사용하지 않고요. 스타일시트 파일에 필요한 css 클래스를 하나 만들어 두고, jQuery의 addClass() 메서드를 사용하여 스타일을 한번에 지정하곤 합니다. 이에 대해서는 뒤에서 다룰 예정입니다.

참 재미있군요.

물론, "별로 재미없는데요"라고 말하시는 분이 있을 수도 있습니다만, 이 기능은 실제 jQuery가 제공하는 막강한 기능의 10%도 안되는 것이라서 아직까지는 감동이 적을 수도 있습니다. 셀렉터를 다루는 것은 jQuery의 멋진 기능을 다루기 위한 기본기라는 것을 기억하셔야 합니다. 지금은 드리볼을 배우는 단계입니다. 아직은 슛을 쏘기에는 이르다는 것이죠.

jQuery 셀렉터 : 컨텐트 필터와 자식 필터

이상 기본 필터에 대해서 알아봤는데요. 이 외에도 몇 개 안되지만 컨텐트 필터와 자식 필터라는 것이 또한 존재합니다. 이 또한 자주 쓰일만한 것이기에 마저 알아보도록 하죠.

먼저 컨텐트 필터입니다. 현재 버전에서는 꼴랑 다음과 같이 4개의 필터가 존재합니다.

< 컨텐트 필터 >

:contains(text) 지정한 텍스트를 포함하는 요소들과 일치됩니다
:empty 자식을 가지지 않는 모든 요소와 일치됩니다. 더불어, 내부 텍스트를 가지지 않는 요소들도 이에 해당됩니다.
:has(selector) 지정된 셀렉터에 해당하는 요소를 갖는 모든 요소들과 일치됩니다.
:parent 부모인 모든 요소들과 일치됩니다. 자식 요소를 갖는 요소 뿐만 아니라 텍스트를 갖는 요소들이 이에 해당됩니다.

별거 아닌 것처럼 보이는 이 필터들, 막상 알고나면, 각각의 필터들이 상당히 유용합니다.

개인적으로는 :empty 필터가 상당히 유용했는데요. 예를 들면, 그리드 출력을 하는 경우에, 값이 누락되어 있는 셀들(td)을 찾아서 그 셀들만 배경색을 회색으로 처리한다거나 할 때는 완전 딱입니다. 물론, contains() 필터와 :has() 필터도 유용하긴 마찬가지 입니다.

다음과 같은 셀렉터를 한번 살펴볼까요?

b:contains('j')
div:has('ul')
table.nameTable td:empty
.nameTable td:contains('F')
table.nameTable tr:eq(0)

첫 번째 셀렉터는 "j"라는 단어를 포함하는 모든 b 요소들을 선택합니다.
두 번째 셀렉터는 모든 div 요소들 중에 ul 요소를 가지고 있는 div 만을 선택합니다.
세 번째 셀렉터는 nameTable이라는 css 클래스가 지정된 table들 중에서 자식 요소인 td 내부에 텍스트 값이 없는(또는 자식요소가 없는) 모든 td를 선택합니다.
네 번째 셀렉터는 nameTable이라는 css 클래스가 지정된 요소들 중에서 그 내부의 td가 텍스트로 "F"란 단어를 포함하고 있는 모든 td를 선택합니다.

마지막 셀렉터는 이미 이전에 다루었던 것이라 굳이 설명할 필요가 없어보이긴 하지만 복습의 차원에서 설명하자면, nameTable이라는 css 클래스가 지정된 table 내의 tr 중에서 첫번째 tr을 선택합니다.

그다지 어렵지 않게 구분이 가능하시죠?

그리고, 기왕 이야기를 하는 김에요. 사실은 이전 강좌에서 이야기할까 하다가 접었던 짧은 이야기를 하나 보태볼까 하는데요. 복습의 차원에서 한번 읽어봐 주시겠어요?

만일, 문서 내에 table 요소가 한 개만 존재하고, 그 table에 nameTable 이라는 css 클래스가 적용이 되었다면, 다음의 셀렉터는 모두 같은 것을 선택한다는 것!

$("table.nameTable tr")
$(".nameTable tr")
$("table tr")
$("tr")

네. 당연한 이야기입니다. 그렇죠? 그래요. 기본 셀렉터의 다양한 형태를 복습의 차원에서 한번 같이 살펴본 것 뿐입니다. 굳이 이러한 이야기를 꺼낸 것은 셀렉터를 처음 접할 경우에는 셀렉터를 어떻게 작성하는 것이 좋은지에 대해 자꾸 걱정하는 분들이 있어서요. 셀렉터는 문서 내에서 원하는 요소를 명확히 찾아낼 수 있는 직관적인 구문이면 뭐든지 오케이입니다. 특별히 어떤 구문이 더 좋다라는 식의 정해진 룰은 없습니다. 물론, 자꾸 사용하시다보면 자신만의 패턴이 생기긴 할 겁니다~(저의 경우는 가급적 구문을 상세하게 작성하는 것을 권합니다)

그러면, 이제 예제를 통해서 컨텐트 필터들의 사용 예를 한번 살펴볼까요?

Filter02.htm

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    
<title></title>
    
<script src="jquery-1.3.2.min.js" type="text/javascript"></script>
    
<script type="text/javascript">
        $(
document).ready(
            
function() {
                $(
"b:contains('j')").css("background""yellow");
                
$("div:has('ul')").css("border""solid 1px green");

                
$("table.nameTable td:empty").css("background""#dddddd");
                
$(".nameTable td:contains('F')").parent().css("background""pink");
                
$("table.nameTable tr:eq(0)").css("background""lightblue");
            
});
    </
script>
    
<style type="text/css">
        
* { font-size:12px; font-family돋움 }
        
.nameTable { background: white; border-collapse:collapse }
    </
style>
</head>
<body>
    
<h3>jQuery란?</h3>
    
<div>
        
<b>jQuery</b>는 가볍고 빠르며, 간결한 오픈소스 스크립트 라이브러리입니다. 
        이를 이용하면 Rich 웹 UI를 개발하는 데 도움이 되는 다양한 기능들 즉,
        
<b>HTML 문서 트래버스</b><b>이벤트 처리</b><b>애니메이션</b><b>Ajax 상호작용
        </b>등을 지원하여 빠르고 견고하게 리치 웹 애플리케이션 개발을 할 수 있도록 지원합니다.
    
</div>
    
<br />
    <
div>
        이러한
<b>jQuery</b>의 기능적인 특징은 다음과 같습니다
    
</div>
    
<br />
    <
div>
        
<ul>
            
<li>막강한 CSS 셀렉터</li>
            
<li>크로스 브라우저 지원</li>
            
<li>메서드 체인</li>
            
<li>Ajax 지원</li>
            
<li>풍부한 플러그 인 지원</li>
        
</ul>
    
</div>
    
<br />
    <
table class="nameTable" border="1" cellpadding="3">
        
<tr><td width="100">이름</td><td width="100">성별</td><td width="100">기타 정보</td></tr>
        
<tr><td>Taeyo</td><td>M</td><td>...</td></tr>
        
<tr><td>Dragon</td><td>M</td><td>...</td></tr>
        
<tr><td>Eric</td><td>M</td><td>...</td></tr>
        
<tr><td>Queeny</td><td>F</td><td>...</td></tr>
        
<tr><td>Youngsun</td><td></td><td>...</td></tr>
        
<tr><td>Hera</td><td>M</td><td>...</td></tr>
        
<tr><td>Secret</td><td>F</td><td>...</td></tr>
    
</table>
</body>
</html>

셀렉터들이 어떤 요소를 선택하고, 어떻게 동작할지는 소스를 보시면 이해가 되실 것입니다. 예제에서 사용한 셀렉터는 이미 예제에 앞서 설명을 드린 셀렉터 그대로이니까요. 다만, 4번째 구문인 다음 구문에서는 parent()라는 처음 보는 메서드가 하나 사용된 것을 보실 수 있을 겁니다.

$(".nameTable td:contains('F')").parent().css("background", "pink");

parent()라는 메서드는 말 그대로 현재 셀렉터에 의해 선택된 개체 집합의 바로 위 부모 개체를 반환하는 메서드입니다. 고로, 이 구문은 .nameTable 이라는 css 클래스를 갖는 개체의 td들 중에서 "F"라는 텍스트를 포함하는 모든 td를 찾아낸 다음(여기까지가 셀렉터), 그의 부모인 tr 개체를 얻어내서( parent 메서드), 그의 배경색을 핑크빛으로 물들이는 것입니다.

그리고, 결과 화면은 이미 여러분이 셀렉터를 해독하여 예상하고 있던 것과 마찬가지로 다음과 같이 나타나게 될 것입니다.

예상대로, b 요소 중 "j"라는 단어가 포함된 것들은 노란 배경색으로 출력되고 있으며, div 요소들 중에서 ul이라는 자식 요소를 가진 개체는 녹색 테두리로 나타나고 있습니다. 또한, 테이블에서 내용이 없는 td는 연한 회색으로 채워져 있으며, td 안의 텍스트가 "F"라는 글자를 포함하고 있으면 그의 부모인 tr이 핑크색으로 출력되는 것을 볼 수 있습니다. 마지막으로, 가장 첫 번째 tr은 연한 파란색으로 출력되고 있고요.

컨텐트 필터는 이처럼 요소의 컨텐트와 관련하여 필터링을 하는데 사용할 수 있는 기능입니다.

컨텐트 필터 외에 또 다른 필터로 자식 필터라는 것도 있습니다. 자식 필터는 말 그대로 현재 요소의 자식들에 대한 필터를 할 수 있는 기능을 제공하는데요. 현재 버전의 jQuery(1.3.2)에서는 다음과 같이 4개의 자식 필터가 제공됩니다.

< 자식 필터 >

:nth-child(index/even/odd) 자식 중 index로 지정된 위치의 요소들과 일치되거나, even, odd에 해당하는 자식들과 일치됩니다. 단, 여기서의 index는 1부터 시작합니다.
:first-child 첫 번째 자식인 모든 요소와 일치됩니다.
:last-child 마지막 자식인 모든 요소와 일치됩니다.
:only-child 자신이 부모 요소의 유일한 자식인 모든 요소와 일치됩니다

처음 이 필터를 접할 경우에는 이전에 다루었던 기본 필터 중 :first, :last와 유사한 필터가 아닐까 하고 생각할 수 있는데요. 사실 이들은 기존의 필터와 상당한 차이가 있습니다.

:first, :last 필터가 단일 요소를 선택하는 반면, 자식 필터들은 단일 요소가 아닌 해당 요소들의 집합을 선택한다는 것이 차이입니다. 예를 들어, 다음 두 셀렉터의 차이를 한번 생각해 볼까요?

td:first
td:first-child

얼핏 보기에는 같은 요소를 선택할 것처럼 보이는 이 둘은 확실한 차이를 보입니다. 즉,

td:first는 현재 테이블 안에서 첫 번째로 나오는 td 하나 만을 선택하는 반면, td:first-child는 현재 테이블 안에서 나오는 첫 번째 수준의 td들을 모두 선택한다는 것이죠. 말로 이해가 잘 안 가시면 다음 그림을 한번 보도록 하세요.

차이가 느껴지시죠?

:nth-child라는 필터도 동작 방식은 동일합니다만, 인덱스를 지정할 수 있거나, even 이나 odd와 같은 값을 지정하여, 짝수나 홀수 번째 그룹이 선택되도록 할 수 있습니다. 심지어는 Xn+Y와 같은 수식을 사용해서 특정 규칙에 따라 선택할 수도 있습니다. 예를 들어, td:nth-child(3n)과 같이 작성하게 되면, 이는 3의 배수에 해당하는 위치의 td 그룹이 선택될 것이며, td:nth-child(2n+1)과 같이 작성하게 되면, 2의 배수에 1을 더한 값에 해당하는 위치의 td 그룹이 선택될 것입니다. 수식에서의 n은 0부터 계산되기에, 3n은 0,3,6,9 .. 에 해당하는 그룹이 되며, 2n+1은 1,3,5,7… 에 해당하는 인덱스 그룹이 선택될 것입니다.

다만, 여기서의 인덱스는 0부터 시작하는 것이 아니라 1부터라는 것에 유념하셔야 합니다. 요 부분이 살짝 짜증(?) 나는 부분이긴 한데요. 앞서 다룬 기본 필터(:even, :odd, :eq(index), :gt(index) 등)에서는 인덱스가 0부터 시작했으나, 자식 필터인 :nth-child에서의 인덱스는 1부터 적용된다는 것이죠.

즉, :first-child와 동일한 것은 :nth-child(1)이지, :nth-child(0)이 아니라는 것입니다. 자식 필터에서 :nth-child(0)은 그 어떤 것과도 일치되지 않습니다. 꼭 기억하세요. 자식 필터를 사용하는 경우에는 인덱스가 1부터 시작한다는 것을요.

이로써, 기본 셀렉터에서 사용할 수 있는 필터들을 어느 정도 정리한 것 같네요. 물론, 아직 visible 관련 필터(2개)가 남아있긴 한데요. 이 부분은 다음 강좌의 시작부에서 가볍게 정리하기로 하겠습니다.

다음 강좌의 본격적인 내용은 사실 셀렉터의 하이라이트라고 할 수 있는 폼 셀렉터에 대한 이야기입니다. 입력 UI를 구현하려면 피해갈 수 없는 폼 요소들을 셀렉터를 이용해서 쉽게 선택할 수 있는 것이 바로 폼 셀렉터인데요. 그러한 셀렉터들을 살펴봄으로써 jQuery의 기본인 셀렉터에 대한 이야기를 완전하게 마무리하도록 하겠습니다.

사실, 이러한 분류는 실제 jQuery 온라인 문서에 나온 분류를 기반으로 말씀을 드리고 있습니다. 해서, 제가 설명드린 셀렉터들에 대해서 개별적으로 조금 더 자세한 설명을 보고 싶다 하시면, http://docs.jquery.com/Selectors 페이지에 가셔서 각각의 셀렉터를 클릭하여 자세한 설명과 함께 라이브 데모 및 소스까지 즐기실 수 있습니다. 꽤 많은 셀렉터가 있지만, 태오와 함께 깔끔한 강좌로 같이 정리해 나가니 생각보다 많게 느껴지시지 않죠? 어쩌면 jQuery의 공식문서보다 저의 강좌가 더 명쾌하게 느껴지실 지도 모르겠습니다(네. 왠지 태오 갑자기 재수가 좀 없군요…).

그러면, 다음 강좌에서 또 뵙겠습니다. 잘 읽으신 분은 /환호 /토닥 한번씩 날려주세요.


authored by Taeyo

Posted by 바람이불면
,

jQuery, 기본 셀렉터

필자의 잡담~

본격적인 jQuery의 기초 설명에 들어갑니다~
그 시작은 셀렉터 입니다~
jQuery란?

jQuery는 가볍고 빠르며, 간결한 오픈소스 스크립트 라이브러리입니다. 이를 이용하면 Rich 웹 UI를 개발하는 데 도움이 되는 다양한 기능들 즉, HTML 문서 트래버스, 이벤트 처리, 애니메이션, Ajax 상호 작용 등을 지원하여 빠르고 견고하게 리치 웹 애플리케이션 개발을 할 수 있도록 지원합니다.

이러한 jQuery의 기능적인 특징을 핵심 키워드만 뽑아서 정리하자면,

  • 막강한 CSS 셀렉터
  • 크로스 브라우저 지원
  • 메서드 체인
  • Ajax 지원
  • 풍부한 플러그 인 지원

정도로 설명할 수 있지 않을까 싶네요. 물론, 이 외에도 많은 것들이 제공되지만 말이죠.

개발 준비사항

처음 jQuery를 공부하고자 맘을 먹고, jQuery 웹 사이트에 가면 이런 생각이 들지도 모르겠습니다.

"에~ 그러니깐, 어디서부터 뭘 어떻게 봐야 하는 거지?"

그렇습니다. 어린 시절부터 완전정복, 맨투맨 류의 참고서적에 길들여져 있는 우리들은 항상 신기술을 접할 때 어떻게 시작해야 할지를 막막해하곤 하죠. 이는 비단 저도 예외가 아닙니다. 하지만, 언제나 신기술이 나왔을 때 가장 좋은 설명서는 해당 웹 사이트에 공개되어 있는 튜토리얼이라는 것은 변함이 없는 사실이지요(물론, 저의 경우는 인터넷 서점에서 관련 서적을 구입한 뒤, 1독이상을 하고 난 뒤에 튜토리얼을 보는 편입니다만, 이는 지극히 개인적인 성향에 따라 다른 부분입니다). 여러분도 성향에 따라 튜토리얼을 보셔도 되고, 제 강좌를 보셔도 되고, 서적을 구매해서 보셔도 됩니다(제 강좌에는 너무 의존하지 마세요 ㅎ).

공부하는 방식은 각자의 선택에 따라 다르지만, jQuery 라이브러리는 모두가 반드시 다운로드 하여 준비해야 하는 사항입니다. 해서, 우선 jQuery를 다운로드 받도록 하죠. http://jquery.com/ 에 가면 메인 화면에서 바로 다운로드가 가능하며, 현재 강좌 작성 기준으로 jQuery의 최신 버전은 1.3.2 를 얻으실 수 있습니다. 그리고, 구하신 파일은 여러분이 작업하는 어떠한 웹 애플리케이션에든지 복사해서 쓰시면 됩니다.

그럼 이제 jQuery의 셀렉터를 이야기하는 것으로 본격적으로 시작해볼까요?

jQuery 셀렉터 : 기본

jQuery의 가장 강력한 부분은 HTML DOM을 마음대로 트래버스 즉, 순회 탐색할 수 있다는 것인데요. 놀랍게도, CSS 셀렉터를 사용하여 원하는 개체를 탐색할 수 있습니다. CSS 셀렉터(Selector)는 대부분의 웹 개발자라면 이미 아실 것이라 생각합니다. 다음과 같이 css 파일에서 사용했던 표현식이 바로 CSS 셀렉터이니까요.

div p {
    font-color
:red;
}

#loginID {
    font-weight
:bold;
    background
:yellow;
}

.Columns {
    padding
:10px;
    background
:white;
}

div p라는 셀렉터는 현재 문서 상에서 div 요소의 자식으로 존재하는 모든 p 요소들에 적용되며, #loginID는 loginID라는 id 값을 가진 요소에, .Columns는 class 어트리뷰트 값으로 Columns를 갖는 모든 요소에 적용되는 것이죠.

이러한 셀렉터를 그대로 jQuery에서 사용할 수 있다는 것은 놀랍습니다. jQuery에서는 원하는 DOM 요소의 그룹을 찾기 위해서 $(selector) 혹은 jQuery(selector)과 같은 표현식을 사용하기에, 위의 3가지 셀렉터를 다음과 같이 사용할 수 있습니다.

$("div p") 혹은 jQuery("div p")
$("#loginID") 혹은 jQuery("#loginID")
$(".Columns") 혹은 jQuery(".Columns")

그리고, 각각의 표현식은 각 DOM 요소의 확장 개체인 jQuery 개체 집합을 반환합니다. DOM 요소를 직접 반환해주는 것이 아니라 그의 래퍼(Wrapper)인 jQuery 개체로 반환해 주기 때문에 직접 DOM 요소를 제어할 때보다 훨씬 편하고 쉽게 개체를 제어할 수 있다는 장점이 있습니다. 예를 들어, $("div p").hide() 와 같은 명령을 사용하면, 현재 문서 상에서 div 요소의 자식으로 존재하는 모든 p 태그집합들은 눈에서 보이지 않게 됩니다. hide()라는 명령은 jQuery 개체가 지원하는 명령이며, 추후 알아보게 될 것인데요. jQuery 셀렉터에 의해 반환되는 개체가 일반 DOM 개체라면 이러한 명령을 사용할 수 없겠지만, jQuery 개체 집합으로 반환되기에 그러한 명령을 사용할 수 있게 되는 것입니다. (아직, hide() 명령의 역할에 대해서는 설명하지 않았지만, 이름만 봐도 기능을 추측할 수는 있겠죠?)

모든 요소를 선택하기 위해서는 $("*")와 같은 표현을 사용할 수 있습니다.

또한, jQuery는 이러한 기본적인 CSS 셀렉터 외에 고급 CSS 셀렉터도 지원합니다. 예를 들면, 계층 셀렉터, 일반 필터 셀렉터, 어트리뷰트 필터 셀렉터 등이 바로 그것인데요. 다음은 계층 셀렉터의 예입니다.

p > a : p 요소 바로 아래 자식인 a 요소(하이퍼링크)와 일치된다.
div + p : div 요소의 바로 다음에 나오는 형제 p 요소와 일치된다.
div ~ p : div 요소의 다음에 나오는 모든 형제 p 요소와 일치된다.

$("p a")와 $("p > a")의 차이점은 전자가 p요소 하위에 존재하는 모든 a 요소를 선택한다면, 후자는 p 요소 바로 아래의 자식으로 놓여있는 a 요소만을 선택한다는 것이 차이입니다.

즉, 다음과 같은 html이 존재한다면,

<p>
    
<span>
        
<a href="1.aspx">1.aspx</a>
    
</span>
    
<br />
    <
a href="2.aspx">2.aspx</a>
</p>

$("p a")는 1.aspx 링크와 2.aspx 링크 모두를 선택하지만, $("p > a")는 2.aspx 링크만을 선택한다는 것이죠.

div + p 및 div ~ p 와 같은 경우는 자식이 아니라 형제 요소와 연관이 있습니다. 즉, 다음과 같은 html 있다고 가정할 경우에 말입니다.

<div>앨범 목록입니다</div>
<p>노라조</p>
<span>수퍼맨</span>
<p>이적</p>
<span>다행이다</span>
<p>현진영</p>
<span>Break me down</span> 

$("div + p")는 div 바로 다음에 나오는 형제 수준의 p 요소, 즉, "노라조"를 선택하게 되는 반면, $("div ~ p")는 div 요소 다음에 나오는 형제 요소들 중 모든 p 요소, 즉, "노라조", "이적", "현진영"과 일치된다는 것이죠.

더불어, a[title]이나 a[href^="mailto:"]와 같이 어트리뷰트를 기반으로 하는 필터링도 가능한데요. 특정 어트리뷰트가 존재하거나, 그 어트리뷰트 값이 특정 값으로 시작 혹은 끝나거나, 특정 값을 포함하거나 하는 부분까지 비교해서 선택할 수 있습니다. 다음은 이러한 어트리뷰트 필러의 예입니다.

a[title] : title 어트리뷰트를 갖는 하이퍼 링크와 일치된다.
a[href^="mailto:"] : href 값이 mailto로 시작하는 하이퍼 링크와 일치된다.
a[href$=".pdf"] : pdf 파일에 링크가 걸린 모든 하이퍼링크와 일치된다.
a[href*="taeyo.net"] : taeyo.net이라는 값이 포함되어 있는 모든 하이퍼 링크와 일치된다.
input[type="text"] : text 형식의 입력 컨트롤과 일치된다.

이러한 선택이 가능한 것은 시작부분(^) 혹은 끝부분($)을 가리키는 정규 표현식을 jQuery가 지원하기 때문입니다.

그러면, 우선 지금까지 알아본 셀렉터들, 가장 기본이 되는 이러한 셀렉터들을 한번 정리해보고 넘어가도록 하겠습니다.

jQuery가 지원하는 CSS 셀렉터들

셀렉터 설명
* 모든 요소와 일치
E1 E1(태그명)인 모든 요소와 일치
E1.class E1(태그명) 요소의 클래스가 class와 동일한 요소와 일치
E1.#id E1(태그명) 요소의 id 어트리뷰트 값이 id와 동일한 요소와 일치
E1 E2 E1 요소의 자식인 모든 E2(태그명) 요소와 일치
E1 > E2 E1 요소 바로 아래 자식인 E2 요소와 일치
E1 + E2 E1 요소의 바로 다음에 나오는 형제요소 E2와 일치
E1 ~ E2 E1 요소의 다음에 나오는 모든 형제 E2와 일치
E1[attr] attr 어트리뷰트를 갖는 E1 요소와 일치
E1[attr=val] attr 어트리뷰트의 값이 val을 갖는 E1 요소와 일치
E1[attr^=val] attr 어트리뷰트의 값이 val 값으로 시작하는 E1 요소와 일치
E1[attr$=val] attr 어트리뷰트의 값이 val 값으로 끝나는 E1 요소와 일치
E1[attr*=val] attr 어트리뷰트의 값이 val 값을 포함하는 E1 요소와 일치

그리고, 이러한 셀렉터를 사용하는 가벼운 예제를 한번 같이 해 보도록 하겠습니다. 가상 디렉토리를 하나 만드시고, 다음과 같은 htm 파일을 하나 작성하도록 하세요. 물론, 동일 폴더에는 아까 다운로드 받은 jQuery 자바스크립트 파일(저의 경우, jquery-1.3.2.min.js)이 있어야 하겠죠?

Default.htm

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    
<title></title>
    
<script src="jquery-1.3.2.min.js" type="text/javascript"></script>
    
<script>
        $(
document).ready(
            
function(){
                $(
"#song").css("border""solid 1px silver");
                
$("a[href^='mailto:']").css("background""lightblue");
                
$("input[type='button']").css("background""yellow");

                
$("div ~ b").css("background""#efefef");
                
$("div > b").css("border""1px");
            
});
    </
script>
    
<style type="text/css">
        
* { font-size:12px; font-family:돋움 }
    </
style>
</head>
<body>
    
<div>
        
<span><a href="http://taeyo.net">taeyo.net</a></span>
        
<br />
        <
a href="mailto:taeyo@A.net">태오의 메일주소</a>
        
<p>
            
<input type="button" value클릭~ />
            <
input type="checkbox" />
            <
input type="radio" />
        </
p>
        
        
<div id="song">요즘 노래방에서 부르는 노래 목록입니다</div><br />
        <
b>노라조</b>
        
<span>수퍼맨</span><br />
        <
b>이적</b>
        
<span>다행이다</span><br />
        <
b>현진영</b>
        
<span>Break me down</span>        
    
</div>
</body>
</html>

예제는 간단합니다. jQuery 셀렉터를 사용해서 몇몇 DOM 요소의 스타일을 변경하는 것이 전부이니까요. 그렇다고, 설명을 안하면 뭔가 서운하니깐, 이야기를 한번 해 보죠.

일단, $(document).ready();라는 함수에 대해서는 설명을 드릴 필요가 있을 듯 합니다. 이는 jQuery가 제공하는 이벤트 메서드 중 하나인데요. 문서의 DOM 요소들을 조작 가능한 시점이 되면 자동으로 호출이 되는 이벤트 메서드라고 보시면 됩니다. 굳이 비교하자면, window.onload 이벤트와 유사한 것이라고 보면 되겠네요. 메서드의 인자로는 델리게이트 함수명을 기입하거나, 익명 함수를 작성하면 됩니다. jQuery를 사용하는 경우에는 일반적으로 별도의 델리게이트 함수를 작성하지 않고, 익명함수를 그대로 작성하곤 합니다. 해서, 소스에서도 그렇게 처리한 것을 보실 수 있습니다. 이 방식은 처음에는 뭔가 복잡해 보일 수 있습니다만, 차츰 매우 익숙해지게 되실 것입니다. 사실, $(document).ready()와 windows.onload 이벤트와는 확실한 차이점이 있습니다만, 일단은 비슷하다고만 기억을 하시고요. 나중에 관련 이야기가 본격적으로 펼쳐질 때, 다시 설명드리도록 하겠습니다.

그리고, 익명 함수 내에서는 다양한 jQuery 셀렉터들을 보실 수 있습니다. 일단, 셀렉터로 원하는 DOM 요소를 찾고, css() 라고 하는 jQuery의 메서드를 사용해서 스타일을 매기는 것을 볼 수 있습니다. 기본적으로 DOM 요소는 css() 라는 메서드는 가지고 있지 않지만, jQuery 셀렉터가 반환하는 개체는 jQuery 확장 개체이기에, 이러한 메서드를 사용해서 쉽게 스타일을 매길 수가 있습니다. 각각의 셀렉터가 어떤 DOM 요소와 일치하는 지는 설명을 드리지 않아도 되겠죠? 여러분이 이미 다 아실 수 있을테니까요. 다음은 이번 예제의 실행 결과입니다.

참 쉽죠?

다음 강좌에서는 이렇듯 막강한 셀렉터에 대해서 조금 더 알아볼 예정입니다. 즉, jQuery 셀렉터 필터라는 것에 대해서 살펴볼까 해요. 원래는 같이 하나의 강좌로 올리려 했는데 생각보다 길어져서 기본 셀렉터만 먼저 올리게 되었습니다 ^^; 셀렉터 필터까지 알고 나시면, 여러분은 찾고자 하는 DOM 요소를 정말 편하고 쉽게 얻어내실 수 있다고 장담합니다.

스크립트 라이브러리를 왜 써야 하는가?

물론, 안 써도 됩니다. 매번 스크립트 기능이 필요할 때마다 손수 다 작성해도 뭐라 그럴 사람은 없으니까요. 하지만, 팀 개발을 하는 경우나 유사한 프로젝트를 반복해서 하는 경우에는 여러분 스스로가 가벼운 수준일지라도 자신만의 라이브러리(일반적으로 유틸리티 function들을 모아놓은 js 파일들) 만들어 놓고 있을 것입니다. 그러면서, 뭔가 풍족하고도 믿고 사용할만한 라이브러리는 없을까 둘러보곤 하죠.

일반적으로 우리가 웹 프로젝트에서 공개된 혹은 상용의 스크립트 라이브러리를 사용하려는 데에는 다음과 같은 이유가 있기 때문입니다.

  • 모든 브라우저에서 올바로 동작하는 자바스크립트를 작성하기는 힘들다.
  • 유사한 기능을 위해서 반복적으로 스크립트 코드를 작성하곤 한다.
  • 수 많은 자바스크립트로 인해 사이트의 유지보수가 힘들다.

더 많은 이유가 있겠지만, 결론적으로 말하자면 스크립트 라이브러리를 사용할 경우, 공수(비용과 시간)를 줄일 수 있고, 개발 및 관리하기가 편해지며, 균일한 코드 퀄리티를 유지할 수 있고, 그에 따라 스트레스도 줄어들기 때문이라고 할 수 있을 것입니다. 사실 이것이 서버 측이던 클라이언트 측이던 프레임워크를 도입하는 대표적인 이유이기도 하죠.




authored by Taeyo

Posted by 바람이불면
,