jQuery 입문: 네비게이션 만들기.
오늘은 jQuery를 이용해서 네비게이션(div>ul>li>ul>li) 만들기를 해볼까 합니다. 수직 형태의 네비게이션과 수평 형태의 네비게이션 동작이 약간 달라서 예제를 두 개 준비 했습니다. 예제의 마크업은 같지만 수직, 수평 네비게이션을 구분하기 위해 클래스 이름을 다르게 지정하고 각각 다른 동작을 입혔습니다. CSS를 사용해서 수직 수평 모양을 지정할 수 있지만 적용하지 않았습니다.
수직 네비게이션 만들기
수직 네비게이션의 요구 조건은 다음과 같습니다.
- 큰 메뉴를 클릭하면
- 열려있는 서브 메뉴가 모두 닫히고
- 클릭한 메뉴의 하위 메뉴가 열리며
- 클릭한 메뉴의 글꼴이 굵어진다
- 포커스가 맺히면 클릭한 것처럼 동작한다
수직 네비게이션 예제
수직 네비게이션 HTML
<div class="gnbVr"> <ul> <li><a href="#">#1</a> <ul> <li><a href="#">#1-1</a></li> <li><a href="#">#1-2</a></li> </ul> </li> <li><a href="#">#2</a> <ul> <li><a href="#">#2-1</a></li> <li><a href="#">#2-2</a></li> </ul> </li> <li><a href="#">#3</a> <ul> <li><a href="#">#3-1</a></li> <li><a href="#">#3-2</a></li> </ul> </li> </ul> </div>
수직 네비게이션 JS
<script type="text/javascript">
$(function(){
var gnbVr = $('.gnbVr');
gnbVr.find('>ul>li>ul').hide();
gnbVr.find('>ul>li>a[href=#]')
.click(function(){
gnbVr
.find('>ul>li>ul:visible')
.slideUp(200)
.parent('li')
.removeClass('active')
.find('>a')
.css('fontWeight','');
$(this)
.next('ul:hidden')
.slideDown(200)
.parent('li')
.addClass('active')
.find('>a')
.css('fontWeight','bold');
return false;
})
.focus(function(){
$(this).click();
});
});
</script>
수평 네비게이션 만들기
수평 네비게이션의 요구 조건은 다음과 같습니다.
- 큰 메뉴를 마우스 오버 하면
- 열려있는 서브 메뉴가 모두 닫히고
- 마우스 오버 메뉴의 하위 메뉴가 열리며
- 마우스 오버 메뉴의 글꼴이 굵어진다
- 포커스가 맺히면 마우스 오버한 것처럼 동작한다
- 메뉴 영역에서 마우스가 떠나면
- 서브 메뉴가 모두 닫히고
- 굵은 글꼴을 제거한다
수평 네비게이션 예제
수평 네비게이션 HTML
<div class="gnbHr"> <ul> <li><a href="#">#1</a> <ul> <li><a href="#">#1-1</a></li> <li><a href="#">#1-2</a></li> </ul> </li> <li><a href="#">#2</a> <ul> <li><a href="#">#2-1</a></li> <li><a href="#">#2-2</a></li> </ul> </li> <li><a href="#">#3</a> <ul> <li><a href="#">#3-1</a></li> <li><a href="#">#3-2</a></li> </ul> </li> </ul> </div>
수평 네비게이션 JS
<script type="text/javascript">
$(function(){
var gnbHr = $('.gnbHr');
gnbHr.find('>ul>li>ul').hide();
gnbHr.find('>ul>li>a')
.mouseover(function(){
gnbHr
.find('>ul>li>ul:visible')
.slideUp(200)
.parent('li')
.removeClass('active')
.find('>a')
.css('fontWeight','');
$(this)
.next('ul:hidden')
.slideDown(200)
.parent('li')
.addClass('active')
.find('>a')
.css('fontWeight','bold');
})
.focus(function(){
$(this).mouseover();
})
.end()
.mouseleave(function(){
gnbHr
.find('>ul>li>ul')
.slideUp(200)
.prev('a')
.css('fontWeight','');
});
});
</script>
오늘은 자세한 설명을 생략하겠습니다. 코드가 너무 길죠? 이렇게 메소드 체이닝이 길어지면 메소드 기준으로 줄을 바꿈으로써 코드 가독성을 높일 수 있습니다.
요즘 PHP 열공하고 있는데…
jquery는 PHP나 C언어랑 형태가 많이 다르군요.
PHP도 공부해야 하고 jquery도 공부해야 되고 접근성에 맞게 디자인도 짤줄 알아야 하고 HTML5도 좀더 공부해야 하고….
퍼블리셔가 되기 위해 할께 정말 많네요.
전역한지 4개월이 다되가고 직장도 구해야 하는데 공부해야 될께 많아 답답합니다. ㅠㅠ
그래도 열심히 해야겠죠? ㅎㅎ
수직 네비게이션 예제 에서
클릭하면 하위메뉴가 그냥 닫혀버리는 현상이 자주 발생하는데 왜그럴까요~?
항상 감사히 보고 있습니다~^^
@나레
어느 예제를 말씀하시는 건지 URL을 알려주시면 한번 볼께요.
@EveR™
네, 포기하지 않으시면 분명히 됩니다. ^^
엄마야, 참 깔끔하게 설명 해놓으셨네요
언제나 도움 받고 있습니다 ^^
예제 잘 보고 있습니다. 설명을 너무 잘 해 주셔서 눈에 쏙쏙 들어오네요.
다음 강좌도 기대가 되요~ ^ ^
수평 네비게이션 JS 코드 마크업에서 $gt; 를 > 로 수정해주세요~
새로운 기법인가하고 놀랬습니다.^^;
다른 분도 댓글에서 지적하셨는데..
처음 클릭시 하위메뉴가 열렸다가 다시 닫히니다. 원인을 보니..
.focus(function(){
$(this).click();
});
이거 때문이군요..
포커스 되기전에.. 마우스로 클릭하면 포커스도 함께 되니.. click() 이 2번 되는셈입니다. 수정을 하셔야 겠습니다.
@나레 @문영신
제가 IE에서 따로 테스트를 안했더니 이런 문제가 있는줄 몰랐네요. 다른 브라우저는 click 이벤트를 한 번 발생시키는데 IE는 click, focus 이벤트를 각각 발생한 것으로 처리를 하는군요. 해결 방법을 찾아 볼께요.
수직 메뉴 맥OS FireFox에서도 같은현상입니다~
수직 내비게이션에서, 포커스가 맺힐때 클릭 효과를 주셨는데, 이 경우 포커스 액션과 더불어 클릭 액션이 함께 먹기 때문에 열렸다 닫히는 경우가 있네요.
반대로 클릭 = 포커스, 포커스 = 펑션.. 이 방식을 하면 그런 오작동을 해결할 수 있을거에요.;
@장호연연 @_JUL_
제가 시간이 없어서 이걸 개선을 못 하고 있네요. 조언 고맙습니다. 시도해 볼께요. ^^
수평네비게이션때문에 골머리 앓다 살짝포기(ㅡㅡ)한 상태였는데 정찬명님 글을 보며 공부를 해봐야 하겠네요.
저같은 경우 mouseOver시 하위메뉴가 보여주고 mouseOut 시 하위메뉴가 사라지는 형태로 제작을 하면서 하위메뉴가 상위메뉴를 기준으로 보여지게 하는 형태로 처리(전체폭과 상위메뉴 위치값과 하위메뉴폭을 계산해서)를 하는데 하고 싶은것이 메뉴가 선택되었을때 해당 하위메뉴가 한번 실행되도록 하는것을 해보고 싶었는데 안되네요.
XE기준으로 설명을 하면 이면 하위메뉴가 한번 실행되는….
좀더 욕심을 내면 다른메뉴 보다가 mouseOut 되면 현재 된 메뉴가 다시 활성화 되는 형태까지 되면 좋을련만…. 플래시로는 요즘 거의 이런형태로 사용이 되는데.. 강좌를 하시게 되면 지금말씀드린부분까지 같이 검토해주시면 좋겠어요.^^
[...] NARADESIGN:BLOG var allblet_id = 137025, allblet_type = 4; var allblet_id = 137025, allblet_type = 4; Posted on January 1, 2012 by koreablogarchive. This entry was posted in Archive and tagged jQuery, 네비게이션, 만들기, 입문. Bookmark the permalink. « 조계종 새 종책특보단장에 원담 스님 교육도시 노스캐롤라이나 샬롯에서 유학생 홈스테이,정착서비스,유학업무 합니다. » [...]
저는 이거 코드가 왜 안될까요.
똑같이 적고
.html 확장자로 저장하믄 안되는 거예요? ㄷㄷㄷ;ㅣ
감사합니다.^^정말로 도움이 많이 되네요.
@최하늘
jQuery 라이브러리를 삽입해야 하는데 이 포스트에는 그 설명이 빠져 있습니다.
예제 스크립트보다 위쪽 라인에 다음 코드가 포함되어 있는지 확인해 보세요.
저는 참 무식하게 하고있었군요.
공부공부;;;
html5 공부하면서 도움 많이 받네요 그동안에 몰랐던 것들도 공부 많이 합니다
.focus(function(){
$(this).click();
});
부분을 지우면 어때요?
지워도 결과는 같던데요?
지우니까 닫혀서
다시 눌러야 열리는 상황도 사라지고..
- 포커스가 맺히면 클릭한 것처럼 동작한다
이부분이 사이트를 다시 로드하면서 소용이 없어서 지우던 말던
.focus(function(){
$(this).click();
});
결과가
똑같은 결과가 생겨요.
그러니까 사이트가 다시 로드되면서
- 포커스가 맺히면 클릭한 것처럼 동작한다
부분이 작동되지 않는 오류에 빠진거죠.
이럴 경우 이것은 어떻게 해결할 수 있을까요?
해결하고 싶기는 하거든요.. ㅠ_ㅠ
현재 제 사이트에서 사용중이기는 하나
IE 에서의 오류 때문에
.focus(function(){
$(this).click();
});
부분을 지워버린 상태예요.
@최하늘
그 부분을 지우면 키보드로 조작이 안될껍니다. 저는 모든 브라우저에서 잘 동작 하는데요. 이상하네요.
가로로 100% 적용시킬려구 하는데 ul 값에 막혀서 그런지 가로로 적용이 안되는데 이부분은 어떻게 정리를 해야할까요 ㅡㅠ z-index 값을 줘도 안되던데. position:absolute 값을 줘도 안되요..
소스를 적용해봣는데.. 처음 오버스 내려오는데 똑같은메뉴를 다시 한번더 오버했을경우에.
다시닫힙니다… 이부분은 어떤게 문제인가요?
네비게이션은 틀린 표기법이고…
내비게이션이 맞습니다.
검색 빈도수가 ‘네’가 더 많지만… 여기는 상당히 표준을 따르는 듯 하니…
@익명
사전에는 내비게이션이라고 수록되어 있군요. 알려주셔서 고맙습니다. 사실 제가 표준을 좋아하기는 하지만 절대 맹신하는 사람은 아닙니다. ^^
수평네비게이션 두번클릭되는거 아직 해결안났나요???;;;;;;;;;;^^
혹시 페이지이동 후 현재 페이지에 맞는 메뉴의 하위메뉴가 열려있게 하려면 어떻게 하면 되는지 알 수 있을까요?
@익명
혹시 문제를 해결하시면 제게도 방법을 좀 알려주세요. ^^
@정성호
그것은 자바스크립트만으로 해결할 수 있는 문제가 아닌것 같은데요. ^^
제 글을 보셨군요? 왠지 반가운데요? ㅋㅋ
저도 자바스크립트만으로 해결하리란 생각은 안하구요.
가장 쉽게 현재 페이지의 주소를 체크해서 해당 주소에 맞는 ul>li>ul>li 을 보여주게 하려고 하는데 어디서 어떻게 손을 대야 할지 감이 안와서요.
계속 고민하고 연구해봐야겠습니다.
이 자리를 빌어 좋은 블로그로 인해 많이 배우는 점 감사말씀 드립니다.
댓글 수정이 안되는거 같아 추가합니다.
제가 생각한건 ul>li>ul>li 에 각각의 class를 넣어서 해당 페이지를 검사해서 맞는 class만 보여주려고 했거든요.
그런데 class를 주고 그냥 display:block 식으로 넣어도 보이질 않더라구요.
클릭하지 않더라도
특정 li(ul>li>ul>li 에서 마지막 li)를
보이게 하려면 어떻게 해야 하나요?
display:block 이나 $(‘.className’).show(); 식으로 할 순 없나요?
에구구…..댓글을 도배하는거 같아 죄송합니다.
보니까 display:block 는 안되는데 show()는 되는군요.
각각의 ul에 class를 줘서 해결해야 겠습니다.
^^;
@정성호
잘 해결 되셨기를 빕니다. ^^