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 바람이불면
,