2008년 11월 15일 토요일

간단한 이미지 슬라이더 만들기

과거에는 게시판을 활용한 이미지 갤러리를 활용하는 일이 많았다. 하지만 근래 들어서는 라이트박스 효과와 더불어 슬라이더 형태의 이미지 갤러리를 많이 적용하는 것을 볼 수 있다. 특별히 메인 화면과 같이 콘텐츠의 양이 많은 경우 공간을 효과적으로 활용하기 위한 방법으로 많이 사용된다. 플래시 무비를 활용하는 경우도 있지만 크게 어렵지 않게 자바스크립트를 이용해서도 만들어볼 수 있어서 소개한다.

가장 먼저 다음과 같이 보이도록 마크업과 스타일시트 작업을 한다.
이미지 슬라이더
이미지 목록과 콘트롤 버튼을 정의하고, 목록을 <UL>요소로 정의했다.
<div id="result"></div>
<h1>Image Slider</h1>
<div id="imageSlider">
    <div class="imageList">
        <ul>
            <li><img src="http://www.clearboth.org/study/081112/thumb_01.png" width="84" height="84" alt="썸네일 이미지 1" /></li>
            <li><img src="http://www.clearboth.org/study/081112/thumb_02.png" width="84" height="84" alt="썸네일 이미지 2" /></li>
            <li><img src="http://www.clearboth.org/study/081112/thumb_03.png" width="84" height="84" alt="썸네일 이미지 3" /></li>
            <li><img src="http://www.clearboth.org/study/081112/thumb_04.png" width="84" height="84" alt="썸네일 이미지 4" /></li>
            <li><img src="http://www.clearboth.org/study/081112/thumb_05.png" width="84" height="84" alt="썸네일 이미지 5" /></li>
            <li><img src="http://www.clearboth.org/study/081112/thumb_06.png" width="84" height="84" alt="썸네일 이미지 6" /></li>
            <li><img src="http://www.clearboth.org/study/081112/thumb_07.png" width="84" height="84" alt="썸네일 이미지 7" /></li>
            <li><img src="http://www.clearboth.org/study/081112/thumb_08.png" width="84" height="84" alt="썸네일 이미지 8" /></li>
            <li><img src="http://www.clearboth.org/study/081112/thumb_09.png" width="84" height="84" alt="썸네일 이미지 9" /></li>
            <li><img src="http://www.clearboth.org/study/081112/thumb_10.png" width="84" height="84" alt="썸네일 이미지 10" /></li>
        </ul>
    </div>
    <div class="controller">
        <input type="button" value="◀" title="앞으로" class="btn_prev" />
        <input type="button" value="▶" title="뒤로" class="btn_next" />
    </div>
</div>

이미지 목록을 담은 <UL>요소를 reliative로 정의한 것에 주목하자.
div#imageSlider { position: relative; width: 600px; height: 100px; border: 1px solid #ccc; }
div#imageSlider div.imageList { position: relative; width: 500px; height: 86px; margin: 8px 50px 0; overflow: hidden;  }
div#imageSlider div.imageList ul { position: relative; left: 0; list-style: none; width: 1000px; margin: 0; padding: 0; overflow: hidden; }
div#imageSlider div.imageList ul li { float: left; margin: 0 17px 0 0; }
div#imageSlider div.imageList ul li img { border: 1px solid #ccc; }
div#imageSlider div.controller input { position: absolute; top: 12px; width: 30px; height: 80px; cursor: pointer; }
div#imageSlider div.controller input.btn_prev { left: 10px; }
div#imageSlider div.controller input.btn_next { right: 10px; }
#result { position: relative; top: 0; left: 0; height: 20px; padding: 5px; }
.alert { background: #FF0000; color: #fff; }

자바스크립트를 작성하기 전에 어떻게 작동시켜야 할지를 고민해보자.
이미지 슬라이더 설계도
각각의 이미지들은 <LI>요소로 감싸고, 목록은 <UL>로 감싸 주었다. 그리고, <UL>요소는 <DIV>요소로 감싸고 있다. 좌우로 버튼이 위치해 있다.
위 설계도를 보면 <DIV>요소가 <UL>요소보다 가로 길이가 짧다. 즉, <UL>요소의 일부분만을 보여주도록 구멍 역활을 하고 있다고 보면 된다. 좌우에 위치한 버튼을 선택했을 때 자바스크립트가 <UL>요소의 left 속성 값을 변경하면서 <DIV>요소를 통해 보여지는 위치를 바꾸게 된다. 이것이 이미지 슬라이더의 기본적인 원리이다.

자바스크립트를 살펴보자.

window.onload = function()
{
    res = document.getElementById("result");
    imageSlider(103, 1); // Move Width, Move Item Count
}
HTML 문서가 웹브라우저에 의해 모두(이미지 포함) 렌더링 되면 imageSlider 함수를 실행한다. res 변수는 인덱스 값 등 작동 결과를 임시로 보여주기 위한 것이다.

function imageSlider(w, cnt)
{
    // Global Variable
    imageList = new Object();
    item_width = w*cnt;
    curr_position = 0;
    curr_idx = 0;
    tmp = 0;

    var slider = document.getElementById("imageSlider");
    var groups = slider.getElementsByTagName("div");
    for(var i=0; i < groups.length; i++)
    {
        if(groups[i].className == "imageList") imageList = groups[i].getElementsByTagName("ul")[0]; // Image List (UL Element)
    }
    var lis = imageList.getElementsByTagName("li");
    imageList.style.width = (w * lis.length) + "px";
   
    // Controller
    var bts = slider.getElementsByTagName("input");
    for(var i=0; i<bts.length; i++)
    {
        if(bts[i].type == 'button' && bts[i].className == 'btn_prev')
        {
            bts[i].onclick = function() { sliderPrev(cnt); } // Click To Prev
        }
        else if(bts[i].type == 'button' && bts[i].className == 'btn_next')
        {
            bts[i].onclick = function() { sliderNext(cnt); } // Click To Next
        }
    }
}
imageSlider 함수가 하는 역활은 간단하다. 한번에 이동할 가로 길이의 값과 한번에 이동한 이미지의 수를 정하고, 좌우 버튼의 이벤트를 활성화 시키는 것이다.

function sliderNext(cnt) // Next Behavior
{
    if(curr_idx < 5)
    {
        imageList.style.left = (curr_position - item_width) + "px";
        curr_position -= item_width;
        for(var i=0; i<cnt; i++) curr_idx++;
        res.innerHTML = "Index : " + curr_idx;
        res.className = "";
    }
    else
    {
        res.innerHTML += " / 더이상 이미지가 없습니다";
        res.className = "alert";
    }
}
sliderNext 함수는 <UL>요소의 left 속성값을 현재값에서 한번에 움직여야 할 값을 뺀 값으로 설정하여, 결과적으로 사용자에게 우측에서 좌측으로 이미지들이 한칸씩 움직이는 것처럼 보이게 한다. 한번 움직여 질 때마다 curr_idx 변수는 현재 보이는 <LI>요소의 인덱스 값을 기억하고 있다가 더이상 보여질 <LI>요소(이미지)가 없을 때 경고 메세지를 보여준다.

function sliderPrev(cnt) // Prev Behavior
{
    if(curr_idx > 0)
    {
        imageList.style.left = (curr_position + item_width) + "px";
        curr_position += item_width;
        for(var i=0; i<cnt; i++) curr_idx--;
        res.innerHTML = "Index : " + curr_idx;
        res.className = "";
    }
    else
    {
        res.innerHTML += " / 처음입니다";
        res.className = "alert";
    }
}
sliderPrev 함수 역시 sliderNext 함수와 똑같다. 단지 left 속성 값을 현재 값에서 빼지 않고 더해서 이번에는 좌측에서 우측으로 움직이는 것처럼 보이게 할 뿐이다. 역시 더이상 보여질 이미지가 없는 경우 에러 메세지를 보여준다.

[데모]

댓글 3개:

  1. 좋은팁입니다.. 유용하게 사용하도록 하겠습니다.^^

    답글삭제
  2. @빽짱구 - 2008/11/17 09:59
    ^^ 빽짱구님처럼 잘 하시는 분께 칭찬을 들으니 기분이 좋은걸요~ 저도 빽짱구님 블로그에서 좋은 팁 많이 얻고 있습니다~

    답글삭제
  3. 비밀 댓글 입니다.

    답글삭제