Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

prototype.js기반의 아코디언 메뉴 Accordion v2.0

요즘 prototype.js에 빠져있다. 스크립터가 될려고 하나? 대부분의 시간을 자바스크립트랑 프로토타입을 만지면서 보내고 있는 것 갔다. UX시대가 오면서 자주 쓰이는 메뉴스탕리중 하나가 되어버린 아코디언스타일의 메뉴를 얼마전에 다뤄 보아서 약간 정리해서 올린다.

아코디언이란건 아코디언처럼 내용이 왔다갔다하면서 보여주기 때문에 붙혀진 이름이고 내가 사용한 소스는 stickmanlabs에서 만든 Accordion v2.0이다. 내가 찾은 것 중에는 prototype.js기반으로 되어진 것은 이게 유일한 것 같다. 약간의 버그나 그런 점들은 있긴 하지만 그래도 완성도는 괜찮은 편인것 같다.

해당 페이지에서 다운로드를 할 수 있고 이 라이브러리는 prototype.js 1.5.1.1기반에 script.aculo.us 1.7의 effect효과를 이용해서 만들어졌다. 해당페이지에도 설명이 자세히 나와있어서 그냥 따라해도 어느정도는 할 수 있지만 포스팅할 거리를 찾느라고 약간 정리를 좀 했다.

당연히 일단 사용을 하려면 각 라이브러리를 인클루드 해야 한다.

<script type="text/javascript" src="/script/prototype.js"></script>
<script type="text/javascript" src="/script/effects.js"></script>
<script type="text/javascript" src="/script/accordion.js"></script>



프로토타입을 불러들이고 script.aculo.us를 인클루드 한다. script.aculo.us는 scriptaculous.js?load=effect 같은 형식으로 인클루드 하는게 일단적인데 여기서는 effect부분만을 사용하기 때문에 아예 파일자체를 따로 인클루드 했다. 마지막으로 아코디언 효과를 줄 accrodion.js를 인클루드 한다.


<div id="verticalEx1">
    <h2 class="vertical_toggle">Title Bar</h2>
    <div class="vertical_content">
        <p> 내용 입력 </p>
    </div>

    <h2 class="vertical_toggle">Title Bar</h2>
    <div class="vertical_content">
        <p> 내용 입력 </p>
    </div>

    <h2 class="vertical_toggle">Title Bar</h2>
    <div class="vertical_content">
        <p> 내용 입력 </p>
    </div>
</div>

위의 코드가 기본적인 아코디언 메뉴의 구조이다. 아코디온을 전체 감싸는 div가 하나 있고 그안에 타이틀바는 h2로(어차피 CSS로 다루기 때문에 꼭 h2일 필요는 없다.) 그리고 보이고 감출 내용을 보여줄 div를 넣고 그 안에 해당 내용을 넣는다. 이 구조를 여러개 붙혀서 여러개의 아코디언을 만들 수 있다.

div로 구조를 만들고 class를 통해서 CSS로 크기나 디자인들을 잡아준다.


.vertical_toggle {
    display: block;
    height: 30px;
    width: 400px;
    background-color: #539bdc;
    padding: 0 10px 0 10px;
    line-height: 30px;
    color: #1b2d3d;
    font-weight: normal;
    text-decoration: none;
    outline: none;
    font-size: 13px;
    border-right: 1px solid #2473b9;
    cursor: pointer;
    margin: 0 0 0 0;
}

.vertical_toggle_active {
    background-color: #d7dc53;
    color: #1b2d3d;
    border-right: 1px solid #1b2d3d;
}

.vertical_content {
    background-color: #2b6190;
    overflow: hidden;
    width:420px;
}

.vertical_content p {
    line-height: 150%;
    padding: 5px 10px 15px 10px;
}

vertical_toggle가 기본적으로 나타나는 타이틀바의 스타일이다. dispaly를 block로 주고 높이와 넓이를 준 다음에 그 외의 부분은 원하는 스타일대로 색상이나 배경이미지등을 주면 된다. h2에 기본적으로 커서가 안바뀌므로 cursor을 pointer로 해준다. vertical_toggle_active은 아코디온 메뉴를 오픈했을때 바꾸어줄 스타일이다. h2의 롤오버 메뉴정도를 생각하면 된다. vertical_content는 내용을 보여줄 부분의 div스타일로 배경색등을 주고 overflow를 히든으로 주고  아코디언메뉴를 어느정도 폭으로 해 줄지 여기서 width를 통해서 정해준다.

이제 실제 아코디언메뉴를 동작시킬 자바스크립트 코드를 보자.


// 온로드시 makeAccordion() 실행
Event.observe(window, 'load', makeAccordion, false);

function makeAccordion() {
    //accordion생성
    var verAccordion = new accordion('verticalEx1', {
        classNames : {
            toggle : 'vertical_toggle',
            toggleActive : 'vertical_toggle_active',
            content : 'vertical_content'
        },

        direction : 'vertical'
    });

    verAccordion.activate($$('#verticalEx1 .vertical_toggle')[0]);
}

Event.observe는 prototype.js에서 제공하는 이벤트 리스너 등록이다. prototype.js방식을 전혀 모르면 좀 이해하기가 쉽지 않은데 간단히 말하면 window.onload = fucntion() {}이랑 동일한 거다. Event.observe로 이벤트 리스너를 등록하는데 window가 load될 때에 makeAccordion를 실행시키라는 것이다. 이렇게 하면 페이지가 로딩된 후에 makeAccordion()가 실행이 된다.

makeAccordion()에서 아코디언 을 초기화 해 주는데 accordion을 새로운 클래스로 만들어서 verAccordion이라는 변수에 넣어준다. 클래스를 만들면서 아규먼트로 아코디언 전체를 감싸는 verticalEx1이라는 div의 아이디를 주고 두번째와 세번째 아규먼트로 아코디언에 대한 옵션을 준다.

toggle에 기본타이틀바의 class를 주고 toggleActive에 타이틀바를 클릭했을 때의 class, 그리고 content의 내용 div의 class를 준다. 여기선 세로형 아코디언을 쓸 것이므로 direction으로 vertical을 주면 아코디언에 대한 기본 설정이 완료된다.

verAccordion.activate($$('#verticalEx1 .vertical_toggle')[0]); 코드에서 처럼 생성한 객체.activeate를 통해서 아코디언 메뉴를 활성화 시킨다. 활성화 시킨다는 말은 오픈한다는 얘기다. 여기서는 [0]번째를 activate를 했으므로 처음 로딩 되었을때 첫번째 아코디언이 열린채로 로딩된다. 이 코드가 없으면 모든 아코디언이 닫힌채로 페이지가 로딩된다. 약간 보고 있으면 구조는 그리 어렵지 않다.

세로형 아코디언 효과 예제보기



이번엔 가로형을 보자. 가로형 아코디언 효과는 기본적으로는 거의 비슷하다. <div>의 구조는 완전히 동일하고 Style이 약간 달라지고 자바스크립트로는 direction만 달라지면 된다.


.horizon_toggle {
    float: left;
    display: block;
    height: 200px;
    width: 30px;
    background-color: #539bdc;
    padding: 10px 0 10px 5px;
    line-height: 30px;
    color: #1b2d3d;
    font-weight: normal;
    text-decoration: none;
    outline: none;
    font-size: 13px;
    border-right: 1px solid #2473b9;
    cursor: pointer;
    margin: 0 0 0 0;
}

.horizon_toggle_active {
    background-color: #d7dc53;
    color: #1b2d3d;
    border-right: 1px solid #1b2d3d;
}

.horizon_content {
    height: 220px;
    float: left;
    background-color: #2b6190;
    overflow: hidden;
}

.horizon_content p {
    width: 450px;
    line-height: 150%;
    padding: 5px 10px 15px 10px;
}

가로형의 스타일 구조다. 세로형에서 한번 보았으니 그리 어렵지 않을 것이다. 세로형과 다른 점은 타이틀바의 기본상태인 horizon_toggle부분에 float:feft가 반드시 들어가야 한다. 그리고 보여지는 내용부분이 되는 horizon_content에도 float:left;가 들어가고 이곳에서 높이를 결정해 준다.(높이도 반드시 지정해야 한다. 세로형에서는 이곳에서 width를 지정했다.) 그리고 아키디언이 가로로 펴지는 폭은 horizon_content안의 p부분에 style을 적용한 부분에서 width로 지정해 준다.

script부분은 완전히 동일하지만 direction : 'horizontal' 로 지정하면 된다. 스타일 부분의 필수부분이 빠지면 제대로 동작하지 않는다.

이렇게 지정하면 제대로 동작하지만 약간의 버그가 있다. 세로형에서는 그렇지 않지만 가로형에서는 horizon_content 부분에서 height를 지정해도 아코디언 메뉴를 열면 배경색이 지정한 높이만큼 나오지 않고 콘텐츠의 높이 만큼 배경색이 나온다.(지정한 높이보다 적으면 짧게, 높이보다 크면 더 길게 나온다. 예제의 첫번째 아코디언 참조. 세로형에서도 그렇지만 세로형은 아코디언이 길게 펼쳐지므로 큰 이상이 없다.)

이 부분은 데모사이트에서도 동일한 현상이 나타나는데 중첩을 통해서 배경색을 감춤으로써 해결했다. 약간의 테스트를 해본 결과 중첩을 하고 이 문제를 해결하려면 전체 아코디언을 div로 한번더 감싸고 그 div에 content부분과 동일한 배경색을 지정하고 포지션을 absolute로 주고 위치를 지정하면 된다.(예제의 두번째 아코디언 참조)


.forBackgroud {
    background-color: #2b6190;
    position:absolute;
    top: 400px;
    left: 10px;
}

위 소스인데 이렇게 하면 가능하다. 다른 방법이 또 있는 줄은 모르겠지만 내 테스트 범위 내에서는 저 방법 밖에 없었다. absolute가 아니면 배경색이 나타나지 않는다. 그리고 left를 지정하지 않으면 IE7에서는 위치가 잘못되어 나타난다.

세로형 아코디언 효과 예제보기

중첩해서 사용하는것은 별로 어렵지 않다. 그냥 content부분에 다른 아코디언을 통째로 넣어주면 해결된다.

중첩형 아코디언 효과 예제보기



덧1) 첫아코디언이 닫혀있을때 다시열면 깜딱 거리는 버그가 있는데 이부분은 해결이 안된 상태이다. 이건 script.aculo.us에서도 비슷한 현상이 발생하는데 그때문인듯 하다.

덧2) 소스자체를 좀 분석해 보고픈 욕심도 있지만 아직은 좀 무리라서.... 이외에 더 자세한 부분은 accordion 사이트를 참고하시길...

2008/01/24 03:10 2008/01/24 03:10