NARADESIGN

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


JavaScript를 이용하여 현재 탐색 메뉴 highlighting.

본문 건너 뛰기

자바스크립트를 이용하여 현재 페이지를 참조하는 메뉴 링크를 하이라이팅 처리할 수 있습니다. 아래 데모 페이지에 순차적으로 접근해서 어떤 메뉴가 하이라이팅 되는지 확인해 보세요. 데모는 하나의 HTML 페이지로 구성되어 있으며 URL에 id 값(해시 값)을 붙여서 일부러 여러 개의 주소로 접속하도록 했습니다. 물론 실전에서는 각 메뉴 페이지를 menu1.html, menu2.html 이렇게 서로 다른 페이지로 구성할 텐데요. 원래는 그런 상황에 적용할 목적으로 구현했습니다.

  1. http://s.codepen.io/naradesign/debug/vEeyVv
  2. http://s.codepen.io/naradesign/debug/vEeyVv#menu1
  3. http://s.codepen.io/naradesign/debug/vEeyVv#menu2
  4. http://s.codepen.io/naradesign/debug/vEeyVv#menu3
  5. http://s.codepen.io/naradesign/debug/vEeyVv#menu4
  6. 소스코드 – http://codepen.io/naradesign/pen/vEeyVv

데모는 현재 페이지의 URL과 4개 메뉴의 링크 값을 각각 비교하여 동일한 값이 존재하는 경우 부모 노드인 <li> 요소에 .current 라는 CSS 클래스를 추가합니다. 지금부터 데모에 사용된 코드를 부분적으로 설명합니다. 원본 코드는 소스 코드 보기를 통해 참고하세요.

자바스크립트에서 window.location.href 이라는 전역 객체 프로퍼티를 이용하면 현재 페이지의 URL 값을 알아낼 수 있습니다.

var pageURL = location.href; // 현재 페이지 주소를 pageURL 변수에 할당.

현재 페이지의 URL 값을 <a> 링크의 href 값과 비교하여 일치하는지 확인할 수 있다면 현재 페이지를 참조하는 링크를 찾아내어 하이라이팅 할 수 있겠죠. 링크 값을 menuURL 이라는 변수에 할당합니다.

var menuURL = $this.attr(“href”);  // 메뉴 링크 값을 menuURL 변수에 할당.

변수 pageURL의 값은 문자열인데요. 문자열에는 indexOf() 라는 메서드를 활용해서 일치하는 문자열이 있는지 확인할 수 있습니다.

if ( pageURL.indexOf(menuURL) !== -1 ) {
// 일치하는 문자열이 있으면 이 블록이 실행됨.
// 현재 페이지 URL과 href 속성 값이 일치하는 <a>의 부모 요소에 .current 라는 클래스 추가.
}

indexOf() 메서드는 pageURL 값으로부터 menuURL 값을 검색한 다음 일치하는 문자열이 발견되지 않으면 -1을 반환하고, 일치하는 문자열이 발견되면 일치하는 문자열의 위치가 숫자 값(0, 1, 2, 3…)으로 반환 됩니다. 따라서 -1이 아니라면 일치하는 문자열이 존재한다는 것을 의미합니다. 데모에서는 indexOf() 메서드가 다음과 같은 두 값을 비교했을 것입니다.

pageURL => http://s.codepen.io/naradesign/debug/vEeyVv?#menu1
menuURL => #menu1

#menu1 이라는 문자열이 pageURL 에서 발견됐습니다. 그러므로 if 블록이 실행 되었겠죠.

location.href 전역 객체 프로퍼티와 문자열에 사용할 수 있는 indexOf() 라는 내장 메서드를 활용해서 현재 페이지 링크 하이라이팅 기능을 구현해 봤습니다.

제가 지금 자바스크립트를 공부하는 중이라서 이 포스팅과 관련하여 여러가지 조언을 주시면 넙죽 하고 감사히 받겠습니다.

분류: 자바스크립트 | 2015년 2월 3일, 2:12 | 정찬명 | 댓글: 8개 |
트랙백URI - http://naradesign.net/wp/2015/02/03/2090/trackback/

8개의 댓글이 있습니다.

  1. 익명 댓글:

    비교에 indexOf()를 활용하는 방법 참신하네요.
    그런데 말입니다. 만약에 a_menu.html이라는 href와 menu.html라는 href가 한 페이지에 공존 하면 문제가 발생 되지 않을까요? 둘다 menu.html이라는 문자열을 포함해서 current클래스를 할당받게 될 것 같은데^^
    물론 이런 상황을 피해서 href를 만든다면 괜찮겠지만요.

  2. 정찬명 댓글:

    @익명
    예리한 지적이시네요. 그런 상황을 어떻게 해결해야 할지 숙제로 남았네요. 고민해 보고 답이 나오면 예제를 업데이트 하겠습니다. 고맙습니다.

  3. 멀더끙 댓글:

    1. hash 값으로 비교를 할 것이라면,
    pageURL 로 부터 indexOf 보다는 hash property를 이용해보심이 어떠하실지요? /=ㅁ=/

    2. hash가 URL에 들어갈 경우 페이지 로딩 시 해당 컨텐츠 위치로 이동하는 이슈도 있기 때문에… query string 즉, search property를 이용하는 방법도….

  4. 정찬명 댓글:

    @멀더끙
    URL이 해시값 아닌 경우도 고려하고 있습니다. 그런데 hash 프로파티도 있군요. search 프로퍼티도 공부해 봐야겠네요. 감사합니다.

  5. 장정식 댓글:

    전역객체인 location.href 말고,
    현재 페이지의 href를 받아서 매칭시키는편이 좋을 듯 해요.
    또한 indexOf 메소드 보다는
    pattern을 하나 만들어서 matching 시키는게 좋을 듯 합니다.

    var uri = event.currentTarget.href;
    var pattern = /\#(?:.*)/g;

    uri.match(pattern)[0] 을 하면 결과값이 배열로 리턴되어요.
    즉, 리턴값이 #~이 되는거겠죠.

    디테일한 소스는
    http://codepen.io/js-ordinary/pen/WbZZzN/

    여기서 보시면 될 것 같아요.
    그럼 조만간에 얼굴 한번 뵈어요. 형님 :)

  6. 정찬명 댓글:

    @장정식
    정식이한테 개인 레슨 한 번 받아야겠어. 고마워. ㅎㅎ

  7. 익명 댓글:

    방문할때마다 느끼지만 보석같은 내용같습니다.

  8. 익명 댓글:

    이게 뭐하는거죠?

댓글 쓰기

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

필수 아님

필수 아님