bootstrap-dropdown.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /* ============================================================
  2. * bootstrap-dropdown.js v2.3.1
  3. * http://twitter.github.com/bootstrap/javascript.html#dropdowns
  4. * ============================================================
  5. * Copyright 2012 Twitter, Inc.
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. * ============================================================ */
  19. !function ($) {
  20. "use strict"; // jshint ;_;
  21. /* DROPDOWN CLASS DEFINITION
  22. * ========================= */
  23. var toggle = '[data-toggle=dropdown]'
  24. , Dropdown = function (element) {
  25. var $el = $(element).on('click.dropdown.data-api', this.toggle)
  26. $('html').on('click.dropdown.data-api', function () {
  27. $el.parent().removeClass('open')
  28. })
  29. }
  30. Dropdown.prototype = {
  31. constructor: Dropdown
  32. , toggle: function (e) {
  33. var $this = $(this)
  34. , $parent
  35. , isActive
  36. if ($this.is('.disabled, :disabled')) return
  37. $parent = getParent($this)
  38. isActive = $parent.hasClass('open')
  39. clearMenus()
  40. if (!isActive) {
  41. $parent.toggleClass('open')
  42. }
  43. $this.focus()
  44. return false
  45. }
  46. , keydown: function (e) {
  47. var $this
  48. , $items
  49. , $active
  50. , $parent
  51. , isActive
  52. , index
  53. if (!/(38|40|27)/.test(e.keyCode)) return
  54. $this = $(this)
  55. e.preventDefault()
  56. e.stopPropagation()
  57. if ($this.is('.disabled, :disabled')) return
  58. $parent = getParent($this)
  59. isActive = $parent.hasClass('open')
  60. if (!isActive || (isActive && e.keyCode == 27)) {
  61. if (e.which == 27) $parent.find(toggle).focus()
  62. return $this.click()
  63. }
  64. $items = $('[role=menu] li:not(.divider):visible a', $parent)
  65. if (!$items.length) return
  66. index = $items.index($items.filter(':focus'))
  67. if (e.keyCode == 38 && index > 0) index-- // up
  68. if (e.keyCode == 40 && index < $items.length - 1) index++ // down
  69. if (!~index) index = 0
  70. $items
  71. .eq(index)
  72. .focus()
  73. }
  74. }
  75. function clearMenus() {
  76. $(toggle).each(function () {
  77. getParent($(this)).removeClass('open')
  78. })
  79. }
  80. function getParent($this) {
  81. var selector = $this.attr('data-target')
  82. , $parent
  83. if (!selector) {
  84. selector = $this.attr('href')
  85. selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
  86. }
  87. $parent = selector && $(selector)
  88. if (!$parent || !$parent.length) $parent = $this.parent()
  89. return $parent
  90. }
  91. /* DROPDOWN PLUGIN DEFINITION
  92. * ========================== */
  93. var old = $.fn.dropdown
  94. $.fn.dropdown = function (option) {
  95. return this.each(function () {
  96. var $this = $(this)
  97. , data = $this.data('dropdown')
  98. if (!data) $this.data('dropdown', (data = new Dropdown(this)))
  99. if (typeof option == 'string') data[option].call($this)
  100. })
  101. }
  102. $.fn.dropdown.Constructor = Dropdown
  103. /* DROPDOWN NO CONFLICT
  104. * ==================== */
  105. $.fn.dropdown.noConflict = function () {
  106. $.fn.dropdown = old
  107. return this
  108. }
  109. /* APPLY TO STANDARD DROPDOWN ELEMENTS
  110. * =================================== */
  111. $(document)
  112. .on('click.dropdown.data-api', clearMenus)
  113. .on('click.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
  114. .on('click.dropdown-menu', function (e) { e.stopPropagation() })
  115. .on('click.dropdown.data-api' , toggle, Dropdown.prototype.toggle)
  116. .on('keydown.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
  117. }(window.jQuery);