NARADESIGN

웹표준, 웹접근성, 유니버설디자인, HTML, CSS, UI, UX, UD


jQuery 입문: 레이어 토글 기능 만들기.

본문 건너 뛰기

아직 자바스크립트에 익숙하지 않지만 jQuery 이야기를 해 보려고 합니다. 제가 jQuery를 잘 다루게 된다면 이미 잘 알고 있는 것에 흥미를 잃어버리는 습성 때문에 jQuery 글쓰기를 시도하지 않을것 같아요. 그래서 초심자인 지금이 가장 좋은 타이밍이라고 생각합니다. jQuery를 잘 다루려면 초급 수준의 HTML/CSS 지식이 필요합니다.

jQuery는 지구상에서 가장 인기있는 자바스크립트 라이브러리입니다. 2011년 6월 현재 w3techs.com 통계에 따르면 지구촌 1/3 웹 사이트가 jQuery를 사용하고 있고, 자바스크립트 라이브러리를 사용하는 사이트 중 4/5 웹 사이트가 jQuery를 사용하고 있습니다. 이 정도면 대세라 부를만 하지요.

책을 통해서 자바스크립트나 jQuery를 배우려고 할 때 가장 불만인것은 거의 모든 책들이 기초부터 가르치려고 한다는 점입니다. 물론 저도 책을 쓴다면 그럴것 같긴 해요. 하지만 제가 성질이 급한건지 "당장 써먹을 수 있는 것을 알려주면 참 좋을텐데" 라는 생각을 항상 합니다. 블로그는 당장 써먹을 수 있는 것을 알려주기 참 좋은 도구 입니다. 누군가 궁금해 하는 것을 콕 짚어서 짧게 쓸 수 있고 실행 코드와 예제를 눈앞에 보여줄 수 있으니까요.

오늘의 목표는 자바스크립트를 통해 가장 빈번하게 구현하는 레이어 토글(열고 닫기)을 구현해 볼까 합니다. 아무리 급해도 jQuery 라이브러리를 불러오는 방법 정도는 설명하고 넘어갈께요.

jQuery 라이브러리 참조하기

jQuery 라이브러리는 http://jquery.com/ 웹 사이트를 통해서 최신 버전을 내려받을 수 있습니다. 그러나 jQuery 라이브러리 파일을 다운받지 않고 CDN 서버가 제공하는 파일을 직접 링크해도 됩니다. 저는 jQuery 버전이 올라갈 때마다 업데이트 하는일이 귀찮아서 아예 항상 최신 버전으로 업데이트 되는 경로의 파일 http://code.jquery.com/jquery-latest.min.js 를 링크해서 사용합니다. 다음과 같이 jQuery 라이브러리를 참조할 수 있습니다.

<head>
    …
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
</head>
<body>
    …
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
</body>

일부러 head와 body에 jQuery를 두 번 로드했는데요. 실제로는 이렇게 사용하면 안됩니다. head 또는 body 안쪽의 원하는 위치에 넣을 수 있다는 것을 보여준 것 뿐입니다. head 또는 body 안쪽에 포함할 수 있지만 head, body 밖에서 작성하면 HTML 문법 오류입니다. 자바스크립트를 head에 포함하면 웹 브라우저가 자바스크립트 파일을 해석하는 동안 아직 body 부분을 해석하기 못했기 때문에 사용자는 빈 페이지를 보고 있어야 합니다. 웹 브라우저는 HTML 코드를 작성 순서대로 해석한다는 사실을 잊지 마세요. 물론 순식간에 일어날 일이겠지만 웹 페이지 체감 속도가 느려진다는 뜻입니다. 따라서 body에 넣는 것을 권장하며 body 중에서도 body 가장 아래쪽 body가 끝나기 직전에 삽입하는 것이 좋습니다. body가 로드되기 전에 자바스크립트를 먼저 해석해야만 하는 경우도 간혹 있는데요. 그런 상황이 오면 그 때 head로 옮겨도 늦지 않습니다. 제 블로그도 body 끝나기 직전에 해석하도록 로드해 놨습니다.

jQuery 준비 함수 선언

로드된 jQuery 라이브러리를 이용하려면 jQuery() 또는 $()  함수 안쪽에 jQuery 문법의 스크립트를 작성하면 됩니다. jQuery()와 $()는 같은 표현입니다. 달러 ‘$’ 표시는 jQuery 객체를 의미합니다. jQeury 라이브러리가 로드되면 앞으로 무수히 많이 등장할 모든 달러 ‘$’ 기호를 웹 브라우저는 무조건 jQuery 객체라고 해석할 것입니다. 웹 브라우저는 jQuery 또는 달러 ‘$’ 기호를 만나면 "제이쿼리구만. 이제부터 jQuery 라이브러리에 있는 규칙을 참고해서 뭔가를 선택하거나 실행할께." 라고 말할 것입니다. 아래 코드는 항상 jQuery 라이브러리보다 나중에 선언합니다. jQuery 라이브러리가 먼저 해석이 되어야 jQuery 라이브러리를 이용할 수 있습니다. 

<script type="text/javascript">
$(document).ready(function(){
    // 여기에 작성한 코드는 브라우저가 HTML을 해석을 마칠 때까지 기다렸다가 실행합니다.
});
</script>

이 코드는 (document).ready 부분을 지워서 다음과 같이 축약할 수 있습니다.

<script type="text/javascript">
$(function(){ 
    // 여기에 작성한 코드는 브라우저가 HTML을 해석을 마칠 때까지 기다렸다가 실행합니다.
});
</script>

그러나 다른 자바스크립트 라이브러리와 jQuery를 함께 사용할 우려가 있는 경우 아래와 같이 작성합니다. 또 다른 자바스크립트 라이브러리에서도 달러 ‘$’ 기호를 객체로 사용하고 있어 충돌이 날 수 있기 때문입니다. 이렇게 jQuery.noConflict() 라고 시작 부분에 선언하고 jQuery(function(){ … }) 함수 괄호() 안에 ‘$’를 넣어 두면 jQuery(function($){ … }) 안쪽에서는 충돌 없이 안전하게 달러 ‘$’ 기호를 사용할 수 있습니다.

<script type="text/javascript">
jQuery.noConflict();
jQuery(function($){ 
    // 여기에 작성한 코드는 브라우저가 HTML을 해석을 마칠 때까지 기다렸다가 실행합니다.
});
</script>

웹 브라우저가 HTML 해석을 마칠 때까지 기다렸다가 스크립트를 실행하는 이유가 뭘까요? HTML을 해석하기 전에 스크립트가 실행되면 HTML 요소를 선택해서 뭔가를 실행해야 하는 스크립트는 제대로 실행이 되지 않습니다. 예를 들어 .help 요소를 감춤 상태로 두고 웹 페이지를 로드해야 하는 경우 브라우저가 아직 HTML을 해석하기 전이라면 스크립트는 .help 요소를 찾지 못해 오류를 내고 말 것입니다. 자바스크립트 코드를 어쩔 수 없이 문서 head에 넣어서 HTML보다 먼저 읽히도록 설정해야 하는 경우가 발생할 수 있으니 아예 항상 이렇게 작성하는것이 안전합니다.

요소를 선택하고, 이벤트를 설정하고, 동작을 실행하기

jQuery 사용법은 CSS와 유사합니다. 일단 HTML 객체를 선택하는 방법이 CSS 선택자 사용법과 유사해서 CSS를 잘 다루는 사람은 jQuery에 매우 빠르게 익숙해 질 수 있습니다. jQuery 문법은 대부분 ‘선택 – 실행’ 또는 ‘선택 – 이벤트 받으면 – 실행’ 순으로 작성합니다. button.red 요소를 클릭하면 웹 페이지의 배경색을 붉게 바꾸는 코드를 한번 작성해 보겠습니다. button.white 요소를 클릭하면 다시 흰색이 될 것입니다.

<button class="red">Red</button>
<button class="white">White</button> 

 <script type="text/javascript">
$(function(){ 
    $(‘button.red’).click(function(){ 
        $(‘body’).css(‘background’,’red’); 
    });
    $(‘button.white’).click(function(){
        $(‘body’).css(‘background’,’white’);
    });
});
</script>

HTML 요소를 선택할 때 $(‘…’) 안쪽에 CSS 선택자를 넣습니다. $(‘button.red’)를 선택했죠. 그리고 마침표(.)를 이용하여 .click() 이벤트를 연결했고 .click() 이벤트가 발생했을 때 어떤 함수 (function(){ … }) 를 실행할지 적어줍니다. 함수 안에서는 다시 $(‘body’)를 선택하고 마침표(.)를 이용하여 .css() 함수를 연결합니다. .css() 함수 안에는 이렇게 (‘property’,’value’) 속성과 값을 넣었구요. 아래 버튼을 이용해서 작성한 예제 코드가 웹 페이지를 어떻게 변화시키는지 확인해 보세요.

그러나 오늘의 학습 목표는 이게 아니었죠. 레이어를 토글하는게 목표입니다. 레이어를 토글하는 것은 이 예제보다 조금 더 복잡합니다. 사실 if 문이 필요해요. if (레이어가 닫혀있으면) {열기를 실행} else if (레이어가 열려있으면) {닫기를 실행} 그런데 첫날부터 이렇게 어려운걸 가르칠 리가 없잖아요. 다음을 보세요.

레이어 토글하기

일단 다음과 같은 HTML을 머리속에 그려 넣으세요.

<p><a href="#first">First Anchor</a></p>
<p id="first">First Layer</p>
<p><a href="#second">Second Anchor</a></p>
<p id="second">Second Layer</p>

제 머리속에는 아래와 같은 그림이 그려졌습니다. DOM 구조, HTML 요소, href 값, id 값 이름을 머리속에 넣었습니다.

  • p > a[href=#first]
  • p#first
  • p > a[href=#second]
  • p#second

스크립트를 작성하기 위한 시나리오를 떠올립니다. 일단 레이어 요소 #first, #second를 모두 찾아내어 숨깁니다. 그 다음 href 값이 #first, #second인 요소를 찾습니다. 클릭하는 경우 자신의 href 속성 값을 변수에 할당하고 변수에 할당된 값을 id 값으로 지니고 있는 요소를 선택한 다음 .toggle() 함수를 실행합니다. 마지막에 return false 를 추가하여 .click() 이벤트를 취소합니다. 웹 페이지가 자동으로 URL까지 스크롤 하는 것을 방지하는 목적입니다. 다음과 같은 코드를 작성 했습니다.

<script type="text/javascript">
$(function(){
    $(‘#first, #second‘).hide();
    $(‘a[href=#first], a[href=#second]‘).click(function(){
        var myHref = $(this).attr(‘href’);
        $(myHref).toggle();
        return false;
    });
});
</script>

사실 이 코드는 변수 var myHref = $(this).attr(‘href’); 를 사용하지 않음으로써 다음과 같이 더 단순하게 줄일 수 있습니다.

<script type="text/javascript">
$(function(){
    $(‘#first#second‘).hide();
    $(‘a[href=#first], a[href=#second]‘).click(function(){
        $($(this).attr(‘href’)).toggle();
        return false;
    });
});
</script>

실행 결과는 다음과 같습니다. 링크를 클릭할 때 URL이 닫혀있으면 열리고 URL이 열려있으면 닫히는 동작입니다.

First Anchor

First Layer

Second Anchor

Second Layer

사용된 코드를 한 라인씩 설명하면 다음과 같습니다.

  • $(‘#first, #second‘) – #first 요소와 #second 요소를 동시에 선택 합니다.
  • .hide() – 선택한 요소를 display:none 처리합니다.
  • $(‘a[href=#first], a[href=#second]’) – href 속성 값이 #first, #second인 a 요소를 선택합니다.
  • .click() – 사용자가 클릭 이벤트를 발생시켰을 때 함수를 실행합니다.
  • var myHref = $(this).attr(‘href’) – myHref 라는 변수를 만들고 변수에 $(this).attr(‘href’) 값을 할당 했습니다. $(this)는 클릭된 a 요소입니다. 이어지는 .attr(‘href’) 함수는 href 속성의 값을 구해옵니다. 만약 어딘가에서 .attr(‘href’,’#five’) 이런 작성법을 본다면 이것은 href 속성에 #five라는 값을 셋팅하겠다는 뜻입니다. 그러나 값을 작성하지 않고 속성만 작성하는 경우에는 이미 셋팅되어 있는 값을 구해오라는 명령입니다. 다시한번 정리하면 이 코드는 클릭된 a 요소의 href 속성 값을 구해와서 myHref라는 변수에 담아라 입니다.
  • $(myHref).toggle() – myHref 변수에 저장된 값은 a 요소의 href 속성 값으로써 #first 아니면 #second 일 것입니다. 즉, 숨은 레이어 중에서 클릭된 a 요소의 목적지를 선택했습니다. 이어지는 .toggle() 함수는 선택한 요소에 대하여 display:none과 display:block 상태를 반복합니다. 선택한 요소가 닫혀 있으면 열고, 열려 있으면 닫히도록 동작합니다.
  • return false – .click() 함수가 실행되면 웹 브라우저는 URL까지 자동으로 스크롤을 하는데 이것을 원치 않는 경우 return false 를 반환하여 .click() 이벤트가 취소되었음을 브라우저에 알립니다. 단, 이미 실행된 동작은 취소가 되지 않기 때문에 레이어가 열리고 닫히는 동작은 실행이 취소되지 않습니다.

CSS 선택자를 이용하여 DOM으로부터 HTML 요소를 선택하고, 이벤트 함수를 설정하고, 이벤트가 발생했을 때 실행할 동작을 정의하는 순서로 코드를 작성하는 경우가 대부분입니다. $(‘…’)과 $(…)은 어떻게 다를까요? 괄호() 안에서는 홀따옴표 또는 쌍따옴표 모두 사용할 수 있는데요. 따옴표로 감싸는 경우 브라우저는 감싼 부분을 ‘string(문자열)’으로 해석합니다. 즉, HTML 요소 이름, 아이디 이름, 클래스 이름은 모두 따옴표를 사용해서 감싸줘야 합니다. 그러나 myHref와 같은 경우는 자바스크립트 변수이기 때문에 따옴표로 감싸면 안됩니다. 재미있는 것은 레이어를 토글할 때 .toggle() 함수만 사용할 수 있는게 아니라는 겁니다. 슬라이드 .slideToggle() 페이드 .fadeToggle() 함수를 사용하면 조금 더 미려한 동작이 가능합니다.

참고

분류: 자바스크립트 | 2011년 6월 18일, 4:41 | 정찬명 | 댓글: 25개 |
트랙백URI - http://naradesign.net/wp/2011/06/18/1536/trackback/

25개의 댓글이 있습니다.

  1. sublee 댓글:

    `$` 이름 충돌이 우려될 때에는 `jQuery.noConflict()`를 써보세요.

  2. 정찬명 댓글:

    @sublee
    그 전에 여러 라이브러리 섞어 쓰는 상황을 만나지 않거나 만들지 말아야겠지. 충돌 방지에 관한 내 설명이 부족해서 업데이트 했다. 땡큐. ^^

  3. 나니 댓글:

    qna 아코디언(토글) 쪽은…
    qna 항목이 다수일 가능성이 크니까 일일이 #first, #second, #third
    기입해주는 건 좀 다른 방식으로 구현하는게 더 낫지 않나 싶기도 함.
    (게다가 특정 항목 클릭했을 때 다른 항목들은 다 닫히게 한다던가,
    다른 항목 열린거 그냥 냅두는 방식으로 한다던가 하는 식의 여러가지 방법이
    있을 수도 있고… ㅎㅎ)

    아참. qna 아코디언 기능은 모바일쪽에서는 css3 사용해서
    js 안쓰고도 구현 가능. 이미 알고 있을 수도 있겠지만. (형이니깐!!) ㅋㅋ

  4. 조준수 댓글:

    제이쿼리대신 진도를 써도되는건가요?

    제이쿼리를 배우고있는데 NHN에서 만든 진도라는게 있는걸 봐서요 ^^;;

  5. 최진환 댓글:

    감사합니다. jquery 입문 초보인데 차근차근 배우고 있습니다 .

  6. 정찬명 댓글:

    @조준수
    써도 됩니다. 그러나 두 가지 JS 라이브러리 섞어 쓰는것은 권장하지 않아요.

  7. 조준수 댓글:

    @정찬명
    감사합니다. ^^

  8. 류쨩 댓글:

    jquery 한번 배워보고 싶었는데 자세히 설명해주셔서 하나하나 시도해 보고 있습니다. 좋은 내용 감사합니다^^

  9. 짱.... 댓글:

    많은것을 배웁니다.

  10. 윤군 댓글:

    이렇게 보면 알겠는데 막상 해보려면 외이리 어려운지..그래도 늘 도움이 되서 감사합니다.

  11. Gang----, J.... 댓글:

    정말 감사합니다. 잘 작성되어 있네요.. ㅋㅋ ^^
    번창하세요.~~~

  12. 꼼순 댓글:

    아.. 하나하나 친절한 설명과 예시 너무 감사해요. ^^

  13. 진모씨 댓글:

    유니버셜 CSS 디자인 이런 글에서 a태그는 실질적인 자원을 링크해야 한다고 했는데, jQuery나 js, 또는 책갈피를 쓰면 이는 해당되지 않은것인가요?

  14. 정찬명 댓글:

    @진모씨
    책갈피라고 부르는 것도 유효한 자원에 대한 링크 입니다.

  15. 진모씨 댓글:

    @정찬명
    jQuery같은것도 포함하나요?

  16. 정찬명 댓글:

    @진모씨
    jQuery 관련 질문의 요지 파악이 안됩니다. 구체적으로 표현해 주세요.

  17. 진모씨 댓글:

    @정찬명
    아, 이해했습니다. 감사합니다.
    anchor 태그는 같은 페이지 내의 js를 이용한 기능이든 다른 페이지든 연결을 하면 되는군요, 그게 자원이구요. 맞나요??

  18. 정찬명 댓글:

    @진모씨
    네 연결된 자원의 주소가 JS 제거한 상태에서도 실제로 유효한 것이라면 생각하시는게 맞습니다.

  19. 512 댓글:

    [Jquery,Coffeescript] Div 레이어 출력 Jquery 스크립트…

    원하는 DIV 레이어를 간편하게 프린트 해주는 Div Print Jquery 스크립트 입니다.이 스크립트는 두 개의 메소드를 포함하고 있습니다. printdiv 메소드와 printdiviframe 메소드인데요. 두 출력 메소드 모두 Jquery 라이브러리가 필요하고, printdiviframe 메소드는 JqueryUI 모듈도 필요로 합니다. printdiv……

  20. 성후니 댓글:

    저도 이제 jQuery를 사용하게 되는데 설명이 잘 되어 있어서 도움이 됩니다. 고맙습니다. ~~

  21. 지나가다 댓글:

    다른곳을 클릭하면 닫히게 할수 있나요?
    예를 들어 #1 을 클릭해야 열고 닫는데
    닫을때만 #1 을 클릭하지 않고 아무곳(다른이벤트가 발생하면) 이나
    클릭하면 닫혔으면 합니다.

  22. 익명 댓글:

    ioo oijoiioi ioiioi

  23. rim 댓글:

    궁금한게 있어서 찾고 있던중 우연히 보게됩니다.
    많은 도움이 될꺼 같네요. 감사합니다.^^

  24. 익명 댓글:

    Jquery 의 기초 잘 배우고 갑니다. ㅎㅎ

  25. 익명 댓글:

    정말 감사합니다ㅎㅎ

댓글 쓰기

전송된 글이 나타나지 않는다면 필터링 된 것입니다. dece24앳gmail.com 으로 메일 주세요.
(X)HTML 코드 사용이 가능하지만 소스 코드 출력을 원하시면 <꺽쇠>는 [괄호]로 변환하여 작성해 주세요.

필수 아님

필수 아님