본문으로 바로가기

Dropdown Menu BootStrap

category Code Lab 2016. 9. 29. 13:25

Analysis dropdown Menu Bootstrap

부트스트랩에서 사용되는 드롭다운 메뉴 코드를 소개합니다.

아래의 코드는 웹에서만 사용 가능하도록 리얼 부트스트랩의 코드를 조금 제거하였으며 국제 웹접근성(ARIA)를 준수하고 있습니다.





HTML

다음의 마크업에는 ARIA가 적용되어 있습니다.

html
<div class="container">

  <ul class="nav nav-bar">
    <li class="dropdown">
      <a id="menu1" role="button" data-toggle="dropmenu" href="#" aria-haspopup="true" aria-expanded="false">첫번째 메뉴 <b class="caret"></b></a>
      <ul class="dropdown-menu" aria-labelledby="menu1">
        <li><a href="#">서브메뉴 1-1</a></li>
        <li><a href="#">서브메뉴 1-2</a></li>
        <li><a href="#">서브메뉴 1-3</a></li>
        <li><a href="#">서브메뉴 1-4</a></li>
      </ul>
    </li>
    <li class="dropdown">
      <a id="menu2" role="button" data-toggle="dropmenu" href="#" aria-haspopup="true" aria-expanded="false">두번째 메뉴 <b class="caret"></b></a>
      <ul class="dropdown-menu" aria-labelledby="menu2">
        <li><a href="#">서브메뉴 2-1</a></li>
        <li><a href="#">서브메뉴 2-2</a></li>
        <li><a href="#">서브메뉴 2-3</a></li>
        <li><a href="#">서브메뉴 2-4</a></li>
      </ul>
    </li>
  </ul>

</div>



CSS

다음의 스타일은 사용자 디자인에 적절하도록 커스텀 사용하시기 바랍니다.

css
a {
  color: #337ab7;
  text-decoration: none;
}
.container {
  padding-right: 15px;
  padding-left: 15px;
  margin-right: auto;
  margin-left: auto;
}
.nav {
  padding-left: 0;
  margin-bottom: 0;
  list-style: none;
}
.nav > li {
  position: relative;
  display: block;
}
.nav > li > a {
  position: relative;
  display: block;
  padding: 10px 15px;
}
.nav > li > a:hover,
.nav > li > a:focus {
  text-decoration: none;
  background-color: #eee;
}
.nav:before {
  display: table;
  content: " ";
}
.nav:after {
  clear: both;
}
[role="button"] {
  cursor: pointer;
}
.nav .open > a,
.nav .open > a:hover,
.nav .open > a:focus {
  background-color: #eee;
  border-color: #337ab7;
}
.nav-bar > li {
  float: left;
}
.nav-bar > li > a {
  border-radius: 4px;
}
.nav-bar > li + li {
  margin-left: 2px;
}
.dropdown {
  position: relative;
}
.dropdown-menu {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 1000;
  display: none;
  float: left;
  min-width: 160px;
  padding: 5px 0;
  margin: 2px 0 0;
  font-size: 14px;
  text-align: left;
  list-style: none;
  background-color: #fff;
  -webkit-background-clip: padding-box;
  background-clip: padding-box;
  border: 1px solid #ccc;
  border: 1px solid rgba(0, 0, 0, .15);
  border-radius: 4px;
  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
  box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
}
.dropdown-menu > li > a {
  display: block;
  padding: 3px 20px;
  clear: both;
  font-weight: normal;
  line-height: 1.42857143;
  color: #333;
  white-space: nowrap;
}

.dropdown-menu > li > a:hover,
.dropdown-menu > li > a:focus {
  color: #262626;
  text-decoration: none;
  background-color: #f5f5f5;
}

.open > .dropdown-menu {
  display: block;
}
.caret {
  display: inline-block;
  width: 0;
  height: 0;
  margin-left: 2px;
  vertical-align: middle;
  border-top: 4px dashed;
  border-top: 4px solid \9;
  border-right: 4px solid transparent;
  border-left: 4px solid transparent;
}



Dropdown menu Script

실제 부트스트랩에서 사용되는 드롭다운 JS는 prototype 기반으로 구성되어 있으며 플러그인으로도 사용할 수 있도록 확장되어 있습니다.

하지만 여기서 작성된 코드는 프로토타입과 플러그인 코드를 제거한 것임을 알려드립니다.

JavaScript
+function ($) {
  'use strict';

  // DROPDOWN Menu 클래스 정의
  // =========================
  var selector   = '[data-toggle="dropmenu"]';

  function detectParent($this) {
    var selector = $this.attr('data-target');

    if (!selector) {
      selector = $this.attr('href');
      selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, ''); // strip for ie7
    }

    var $parent = selector && $(selector);

    return $parent && $parent.length ? $parent : $this.parent()
  }

  function checkMenus(e) {
    $(selector).each(function () {
      var $this         = $(this);
      var $parent       = detectParent($this);
      var relatedTarget = { relatedTarget: this };

      if (!$parent.hasClass('open')) return;

      if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return;

      $parent.trigger(e = $.Event('hide.dropmenu', relatedTarget));

      if (e.isDefaultPrevented()) return;

      $this.attr('aria-expanded', 'false');
      $parent.removeClass('open').trigger($.Event('hidden.dropmenu', relatedTarget))
    })
  }

  function toggle (e) {
    var $this = $(this);
    var $parent  = detectParent($this);
    var isActive = $parent.hasClass('open');

    checkMenus();

    if (!isActive) {

      var relatedTarget = { relatedTarget: this };
      $parent.trigger(e = $.Event('show.dropmenu', relatedTarget));

      if (e.isDefaultPrevented()) return;

      $this
        .trigger('focus')
        .attr('aria-expanded', 'true');

      $parent
        .toggleClass('open')
        .trigger($.Event('shown.dropmenu', relatedTarget))
    }

    return false
  }

   function dropKeydown(e) {
    if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return;

    var $this = $(this);

    e.preventDefault();
    e.stopPropagation();

    var $parent  = detectParent($this);
    var isActive = $parent.hasClass('open');

    if (!isActive && e.which != 27 || isActive && e.which == 27) {
      if (e.which == 27) $parent.find(selector).trigger('focus');
      return $this.trigger('click')
    }

    var desc = ' li a';
    var $items = $parent.find('.dropdown-menu' + desc);

    if (!$items.length) return;

    var index = $items.index(e.target);

    if (e.which == 38 && index > 0) index--; // up
    if (e.which == 40 && index < $items.length - 1) index++; // down
    if (!~index) index = 0;

    $items.eq(index).trigger('focus')
  }

  // 드롭메뉴 요소에 적용하기
  // ==================

  $(document)
    .on('click.dropmenu.ck', checkMenus)
    .on('click.dropmenu.ck', selector, toggle)
    .on('keydown.dropmenu.key', selector, dropKeydown)
    .on('keydown.dropmenu.key', '.dropdown-menu', dropKeydown)

}(jQuery);




Preview Dropdown Menu

See the Pen dropdown menu by jaeheekim (@jaehee) on CodePen.




[출처] Bootstrap: dropdown.js ver 3.3.6

* http://getbootstrap.com/javascript/#dropdowns



Jaehee's WebClub