본문으로 바로가기

Accessibility Skip Navigation Script

category Code Lab 2016. 5. 21. 07:00

Skip Navigation Script(접근성 스킵 네비게이션)

이 포스팅에서는 일반적으로 CSS로 처리하는 스킵네비게이션을 좀더 풍부하게 하기 위해 스크립트를 가미한 스킵 네비게이션입니다.



HTML

html
<div id="skip-menu">
  <a href="#menu">메뉴 바로가기</a>
  <a href="#container">본문 바로가기</a>
</div>

<div id="header">  
  <h1>header </h1><br />
  <div id="menu">
    menu 1. <br />
    menu 2. <br />
    menu 3. <br />
    menu 4. <br />
    menu 5. 
  </div>
</div>
<br />
<div id="container">
  <h2>Container</h2>
  컨테이너~~ 블라..블라~~ <br />
  컨테이너~~ 블라..블라~~ <br />
  컨테이너~~ 블라..블라~~ <br />
  컨테이너~~ 블라..블라~~ <br />
  컨테이너~~ 블라..블라~~ <br />
  컨테이너~~ 블라..블라~~ <br />
  컨테이너~~ 블라..블라~~ <br />
  컨테이너~~ 블라..블라~~ <br />
  컨테이너~~ 블라..블라~~ <br />
  컨테이너~~ 블라..블라~~ <br />
</div>



CSS

css

/*  
 * @ Define skip-navigation
 * -------------------------------
 */
.skipNav-container a {display: block;padding: 10px 5px; background: #34c0ff; color: #fff; text-align: center; font-variant: small-caps; }
.skipNav-container a:focus {outline: none;background: #e30816;}
.a11y-hidden {overflow: hidden; clip:rect(0 0 0 0); clip:rect(0,0,0,0); position: absolute;width: 1px;height: 1px;margin: -1px;border: 0;padding: 0; }
.a11y-hidden.focusable:focus, .a11y-hidden.focusable:active {outline: visible; clip:auto; position: static; width: auto;height: auto;margin: 0;}

#header {margin: 20px auto; width: 700px;}
#container {margin: 0 auto; width: 700px;}



javaScript

javascript
/* Skip Navigation UI */

$.extend($, {
    'version' : $.fn.jquery,
    'ex' : $.expr[':'],
    'activeElement' : function() {
        return document.activeElement;
    }
});

$.extend($.ex, {
    'focusable' : function(el) {
      el.focus();
      return el === $.activeElement();
    }
});

var skipNavPlugIn = 'skipNav';

var _skipNav ={
    // 초기화 수행
    'init' : function($el, options, callback) {
        this.$el = $el.eq(0);
        this.$link = this.$el.find('a');
        this.options = $.extend(true, {}, $.fn[skipNavPlugIn].defaults, options);
        this.controls();
        this.events();
      
        return this;
    },
  
    'controls' : function() {
        this.$el.addClass(this.options.containerClass);
        this.$link.addClass(this.options.linkClasses.hidden + ' ' + this.options.linkClasses.focusable);
    },
  
    'events' : function() {
        this.$el.on('click', 'a', $.proxy(this.linksAction, this));
    },
  
    'linksAction' : function(e) {
        e.preventDefault();
        var path = e.target.getAttribute('href');
        var $target = $(path);
        if(this.options.setContainerFocusing) {
            $target
                .attr('tabindex', 0)
                .focus()
                .on('blur', $.proxy(this.setTabIndexMinus, $target));
        } else {
            $target.find('*:focusable').eq(0).focus();
        }
        this.options.setHash && (window.location.hash == path);
    },
  
    'setTabIndexMinus' : function() {
        this.attr('tabindex', -1);
    }
};

if(!$.fn[skipNavPlugIn]) {
    $.fn[skipNavPlugIn] = function(options, callback) {
        _skipNav.init(this, options);
    };
    
    $.fn[skipNavPlugIn].defaults = {
        'containerClass' : 'skipNav-container',
        'linkClasses' : {
            'hidden' : 'a11y-hidden',
            'focusable' : 'focusable'
        },
        'setHash' : false,
        'setContainerFocusing' : true
    }
}

$(function() {
    // $.skipNav() 사용법
    // skipNav() 를 적용할 컨테이너 요소 선택자 전달
    var $skip = $('#skip-menu');
    if(!!$skip.length) $skip.skipNav();
});




Result View