본문 바로가기
IT이야기

좌우로 드래그되는 내비게이션 메뉴

by 누리조아 2024. 8. 31.
반응형



1. 좌우 드래그 내비게이션 결과물

반응형 내비게이션을 개발하다가 모바일에서 화면 너비의 협소함으로 인해 좌우로 드래그할 수 있는 내비게이션을 개발해야 할 때가 있었습니다.

그래서 이전의 가운데 세로바를 좌우로 드래그하며 비포 애프터 사진을 비교하는 예제를 참고해서 구현해 보았습니다.

어떻게 동작하는지 아래 동영상을 참고해 보시기 바랍니다.

 



2. 결과 이미지

기능구현에 초점을 맞추었기 때문에 전체적인 구조와 디자인은 간략하게 구성하였습니다.



3. 사전에 임포트(import) 해야 하는 파일 및 플러그인

외부의 라이브러리와 스타일시트를 순서에 맞게 임포트하고, 활용하는 것은 매우 중요한 요소입니다.

이 예제에서는 아래와 같은 순서로 필요한 파일들을 head 영역 안에 임포트를 했습니다.


<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<link rel="stylesheet" href="./css/drag_nav.css">
<script src="./js/jquery-1.12.4.min.js?ver=210618"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.3/jquery.ui.touch-punch.min.js"></script>


(1) jquery-ui.css 파일은 드래그가 가능한 DOM 요소의 스타일 내용이 포함된 파일입니다.

(2) drag_nav.css 파일에는 이번 과제에 필요한 스타일을 정의해 놓았습니다.

(3) jquery-1.12.4.min.js는 jquery를 활용하기 위해 js 파일 중에 가장 먼저 임포트를 했습니다.

(4) jquery-ui.min.js 파일에는 드래그 기능을 구현하는 핵심 내용이 포함되어 있습니다.

(5) jquery.ui.touch-punch.min.js 파일은 모바일에서 터치 이벤트와 마우스 이벤트가 호환되어 동작할 수 있는 기능을 제공하는 파일입니다.

 

4. HTML 구조

좌우 드래그 내비게이션 메뉴의 기능을 구현하기 위해 메뉴의 기본 구조를 아래와 같이 구성하였습니다.


<div class="container">
	<div class="tab_box">
		<ul class="tab_ul">
			<li><a href="http://daum.net">Daum</a></li>
			<li><a href="http://nate.com">Nate</a></li>
			<li><a href="http://google.com">Google</a></li>
			<li><a href="http://tistory.com">Tistory</a></li>
			<li><a href="http://zum.com">Zum</a></li>
			<li><a href="http://korea.com">Korea</a></li>
			<li><a href="http://netian.com">Netian</a></li>
			<li><a href="http://unitel.co.kr">Unitel</a></li>
			<li><a href="http://blog.miz.co.kr">Miz</a></li>
			<li><a href="http://invil.org">Invil</a></li>
			<li><a href="http://blueblog.ohmynews.com">Ohmynews</a></li>
			<li><a href="http://tumblr.com">Tumblr</a></li>
		</ul>
	</div>
</div>


실제 마우스 또는 손가락으로 좌우 슬라이드가 되는 타깃 객체는 '.tab_ul'입니다.

그리고 '.tab_box'는 '.tab_ul'이 좌우로 이동할 수 있는 무대라고 이해하시면 됩니다.

 

5. CSS 스타일

 


@charset "UTF-8";
*{margin:0;padding:0;box-sizing:border-box;}
body{width:100vw;height:100vh;position:relative;background:#666;}
.container{
    position:absolute;
    top:50%;left:50%;
    transform:translate(-50%,-50%);
    width:100%;
    max-width:600px;
    height:400px;
    background:#efefef;
}
/*------------------*/
.tab_box{
    overflow:hidden;
    height:60px;
    background:#ddd;
    box-sizing:border-box;
    -ms-box-sizing:border-box;
    -o-box-sizing:border-box;
    -moz-box-sizing:border-box;
    -webkit-box-sizing:border-box;
}
.tab_box *{
    box-sizing:border-box;
    -ms-box-sizing:border-box;
    -o-box-sizing:border-box;
    -moz-box-sizing:border-box;
    -webkit-box-sizing:border-box;
}
.tab_box .tab_ul{
    display:inline-block;
    overflow:hidden;
    background:#ccc;
}
.tab_box .tab_ul:after{
    display:block;
    visibility:hidden;
    clear:both;
    content:"";
}
.tab_box .tab_ul li{
    float:left;
    background:#bbb;
}
.tab_box .tab_ul li:nth-child(odd){
    background:#aaa;
}
.tab_box .tab_ul li a{
    display:block;
    border:1px solid blue;
    height:60px;
    line-height:60px;
    padding:0 20px;
    font-size:1.2em;
}



위 스타일의 중요한 사항은 아래와 같습니다.

  • '.tab_box'는 '.tab_ul'이 좌우로 이동할 수 있는 영역이기 때문에 자신의 범위를 벗어나는 상황을 대비해서 overflow를 hidden으로 설정해야 합니다.
  • 내비게이션 메뉴에 해당하는 요소(.tab_box .tab_ul li)는 가로로 나열(float:left)해야 합니다.

 

6. 자바스크립트 코딩

 


$(function(){
	// .tab_box의 초기 너비를 계산
    var tnv_wd = $('.tab_box').width();
    var tnv_li_wd = 0;
    $('.tab_ul li').each(function(){ tnv_li_wd += $(this).width(); });
    $('.tab_ul').css('width',tnv_li_wd+2);
    var tnv_ul_wd = $('.tab_ul').width();
    var twd_delta = tnv_wd - tnv_ul_wd;
    
	// .tab_ul요소에 드래그 기능을 설정
    $('.tab_ul').draggable({
        axis : 'x',
        drag : function(event,ui){
            if(twd_delta < 0 && ui.position.left > 0){
                ui.position.left = 0;
            }else if(twd_delta < 0 && ui.position.left < twd_delta){
                ui.position.left = twd_delta;
            }
        }
    });
    
    if(tnv_wd >= tnv_ul_wd){
        $('.tab_ul').draggable('disable');
    }else{
        $('.tab_ul').draggable('enable');
    }
    
    // 창 크기에 변경이 발생할 때마다 .tab_box의 너빗값을 업데이트
    $(window).resize(function(){
        tnv_wd = $('.tab_box').width();
        twd_delta = tnv_wd - tnv_ul_wd;
        if(tnv_wd >= tnv_ul_wd){
            $('.tab_ul').draggable('disable');
            $('.tab_ul').css('left',0);
        }else{
            $('.tab_ul').draggable('enable');
        }
    });
});

 

 

위 소스코드의 핵심 내용은 아래와 같습니다.

 

(1) '.tab_box'와 '.tab_ul'의 너비는 동적으로 계산해야 합니다.

(2) jquery-ui의 draggable() 함수를 활용해서 '.tab_box'에 드래그 기능을 추가 했으며 여기서 x 방향으로만 움직일 수 있도록 제한은 두었습니다.

(3) '.tab_box'와 '.tab_ul'의 너비를 실시간으로 감지하면서 '.tab_ul'이 '.tab_box'를 벗어나지 못하도록 하였습니다.

(4) 창 크기에 변동이 일어날 때마다  '.tab_box'와 '.tab_ul'의 너비를 비교하여 '.tab_box'의 너비가 더 클 경우에는 '.tab_box'의 draggable()을 비활성화하고, 그 반대일 경우에는 활성화하면 됩니다.

 

위의 코드에서는 Touch Punch에 대한 코드가 언급되어 있지 않지만, 내부적으로 모바일 기기에서도 호환성 있게 동작하게 되어 있습니다.

 

결론적으로 이 기능을 구현함으로써 모바일 기기에 대한 공간 제한에 대한 문제를 해결함으로써, PC뿐만 아니라 모바일에서의 사용성이 향상될 수 있습니다.

반응형