mirror of
https://github.com/twbs/bootstrap.git
synced 2025-08-06 13:46:42 +02:00
change dropdown strategy to use an overlay - fixes mobile click anywhere + allows for firefox middle click
This commit is contained in:
139
js/dropdown.js
139
js/dropdown.js
@@ -18,123 +18,101 @@
|
||||
* ============================================================ */
|
||||
|
||||
|
||||
!function ($) {
|
||||
|
||||
"use strict"; // jshint ;_;
|
||||
!function ($) { "use strict";
|
||||
|
||||
|
||||
/* DROPDOWN CLASS DEFINITION
|
||||
* ========================= */
|
||||
// DROPDOWN CLASS DEFINITION
|
||||
// =========================
|
||||
|
||||
var toggle = '[data-toggle=dropdown]'
|
||||
, Dropdown = function (element) {
|
||||
var $el = $(element).on('click.dropdown.data-api', this.toggle)
|
||||
$('html').on('click.dropdown.data-api', function () {
|
||||
$el.parent().removeClass('open')
|
||||
})
|
||||
}
|
||||
var backdrop = '.dropdown-backdrop'
|
||||
var toggle = '[data-toggle=dropdown]'
|
||||
var Dropdown = function (element) {
|
||||
var $el = $(element).on('click.dropdown.data-api', this.toggle)
|
||||
$('html').on('click.dropdown.data-api', function () {
|
||||
$el.parent().removeClass('open')
|
||||
})
|
||||
}
|
||||
|
||||
Dropdown.prototype = {
|
||||
Dropdown.prototype.toggle = function (e) {
|
||||
var $this = $(this)
|
||||
|
||||
constructor: Dropdown
|
||||
if ($this.is('.disabled, :disabled')) return
|
||||
|
||||
, toggle: function (e) {
|
||||
var $this = $(this)
|
||||
, $parent
|
||||
, isActive
|
||||
var $parent = getParent($this)
|
||||
var isActive = $parent.hasClass('open')
|
||||
|
||||
if ($this.is('.disabled, :disabled')) return
|
||||
clearMenus()
|
||||
|
||||
$parent = getParent($this)
|
||||
|
||||
isActive = $parent.hasClass('open')
|
||||
|
||||
clearMenus()
|
||||
|
||||
if (!isActive) {
|
||||
$parent.toggleClass('open')
|
||||
}
|
||||
|
||||
$this.focus()
|
||||
|
||||
return false
|
||||
if (!isActive) {
|
||||
$('<div class="dropdown-backdrop"/>').insertBefore($(this)).on('click', clearMenus)
|
||||
$parent.toggleClass('open')
|
||||
}
|
||||
|
||||
, keydown: function (e) {
|
||||
var $this
|
||||
, $items
|
||||
, $active
|
||||
, $parent
|
||||
, isActive
|
||||
, index
|
||||
$this.focus()
|
||||
|
||||
if (!/(38|40|27)/.test(e.keyCode)) return
|
||||
return false
|
||||
}
|
||||
|
||||
$this = $(this)
|
||||
Dropdown.prototype.keydown = function (e) {
|
||||
if (!/(38|40|27)/.test(e.keyCode)) return
|
||||
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
var $this = $(this)
|
||||
|
||||
if ($this.is('.disabled, :disabled')) return
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
|
||||
$parent = getParent($this)
|
||||
if ($this.is('.disabled, :disabled')) return
|
||||
|
||||
isActive = $parent.hasClass('open')
|
||||
var $parent = getParent($this)
|
||||
var isActive = $parent.hasClass('open')
|
||||
|
||||
if (!isActive || (isActive && e.keyCode == 27)) {
|
||||
if (e.which == 27) $parent.find(toggle).focus()
|
||||
return $this.click()
|
||||
}
|
||||
|
||||
$items = $('[role=menu] li:not(.divider):visible a', $parent)
|
||||
|
||||
if (!$items.length) return
|
||||
|
||||
index = $items.index($items.filter(':focus'))
|
||||
|
||||
if (e.keyCode == 38 && index > 0) index-- // up
|
||||
if (e.keyCode == 40 && index < $items.length - 1) index++ // down
|
||||
if (!~index) index = 0
|
||||
|
||||
$items
|
||||
.eq(index)
|
||||
.focus()
|
||||
if (!isActive || (isActive && e.keyCode == 27)) {
|
||||
if (e.which == 27) $parent.find(toggle).focus()
|
||||
return $this.click()
|
||||
}
|
||||
|
||||
var $items = $('[role=menu] li:not(.divider):visible a', $parent)
|
||||
|
||||
if (!$items.length) return
|
||||
|
||||
var index = $items.index($items.filter(':focus'))
|
||||
|
||||
if (e.keyCode == 38 && index > 0) index-- // up
|
||||
if (e.keyCode == 40 && index < $items.length - 1) index++ // down
|
||||
if (!~index) index=0
|
||||
|
||||
$items.eq(index).focus()
|
||||
}
|
||||
|
||||
function clearMenus() {
|
||||
$(toggle).each(function () {
|
||||
getParent($(this)).removeClass('open')
|
||||
})
|
||||
$(backdrop).remove()
|
||||
$(toggle).each(function () { getParent($(this)).removeClass('open') })
|
||||
}
|
||||
|
||||
function getParent($this) {
|
||||
var selector = $this.attr('data-target')
|
||||
, $parent
|
||||
|
||||
if (!selector) {
|
||||
selector = $this.attr('href')
|
||||
selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
|
||||
}
|
||||
|
||||
$parent = selector && $(selector)
|
||||
var $parent = selector && $(selector)
|
||||
|
||||
if (!$parent || !$parent.length) $parent = $this.parent()
|
||||
|
||||
return $parent
|
||||
return $parent && $parent.length ? $parent : $this.parent()
|
||||
}
|
||||
|
||||
|
||||
/* DROPDOWN PLUGIN DEFINITION
|
||||
* ========================== */
|
||||
// DROPDOWN PLUGIN DEFINITION
|
||||
// ==========================
|
||||
|
||||
var old = $.fn.dropdown
|
||||
|
||||
$.fn.dropdown = function (option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('dropdown')
|
||||
var data = $this.data('dropdown')
|
||||
|
||||
if (!data) $this.data('dropdown', (data = new Dropdown(this)))
|
||||
if (typeof option == 'string') data[option].call($this)
|
||||
})
|
||||
@@ -143,8 +121,8 @@
|
||||
$.fn.dropdown.Constructor = Dropdown
|
||||
|
||||
|
||||
/* DROPDOWN NO CONFLICT
|
||||
* ==================== */
|
||||
// DROPDOWN NO CONFLICT
|
||||
// ====================
|
||||
|
||||
$.fn.dropdown.noConflict = function () {
|
||||
$.fn.dropdown = old
|
||||
@@ -152,13 +130,12 @@
|
||||
}
|
||||
|
||||
|
||||
/* APPLY TO STANDARD DROPDOWN ELEMENTS
|
||||
* =================================== */
|
||||
// APPLY TO STANDARD DROPDOWN ELEMENTS
|
||||
// ===================================
|
||||
|
||||
|
||||
$(document)
|
||||
.on('click.dropdown.data-api', clearMenus)
|
||||
.on('click.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
|
||||
.on('click.dropdown-menu', function (e) { e.stopPropagation() })
|
||||
.on('click.dropdown.data-api' , toggle, Dropdown.prototype.toggle)
|
||||
.on('keydown.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
|
||||
|
||||
|
Reference in New Issue
Block a user