Layout von Websiten mit Bootstrap und Foundation
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

dropdown.js 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  1. /*!
  2. * Bootstrap dropdown.js v4.5.0 (https://getbootstrap.com/)
  3. * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
  4. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  5. */
  6. (function (global, factory) {
  7. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('popper.js'), require('./util.js')) :
  8. typeof define === 'function' && define.amd ? define(['jquery', 'popper.js', './util.js'], factory) :
  9. (global = global || self, global.Dropdown = factory(global.jQuery, global.Popper, global.Util));
  10. }(this, (function ($, Popper, Util) { 'use strict';
  11. $ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $;
  12. Popper = Popper && Object.prototype.hasOwnProperty.call(Popper, 'default') ? Popper['default'] : Popper;
  13. Util = Util && Object.prototype.hasOwnProperty.call(Util, 'default') ? Util['default'] : Util;
  14. function _defineProperties(target, props) {
  15. for (var i = 0; i < props.length; i++) {
  16. var descriptor = props[i];
  17. descriptor.enumerable = descriptor.enumerable || false;
  18. descriptor.configurable = true;
  19. if ("value" in descriptor) descriptor.writable = true;
  20. Object.defineProperty(target, descriptor.key, descriptor);
  21. }
  22. }
  23. function _createClass(Constructor, protoProps, staticProps) {
  24. if (protoProps) _defineProperties(Constructor.prototype, protoProps);
  25. if (staticProps) _defineProperties(Constructor, staticProps);
  26. return Constructor;
  27. }
  28. function _defineProperty(obj, key, value) {
  29. if (key in obj) {
  30. Object.defineProperty(obj, key, {
  31. value: value,
  32. enumerable: true,
  33. configurable: true,
  34. writable: true
  35. });
  36. } else {
  37. obj[key] = value;
  38. }
  39. return obj;
  40. }
  41. function ownKeys(object, enumerableOnly) {
  42. var keys = Object.keys(object);
  43. if (Object.getOwnPropertySymbols) {
  44. var symbols = Object.getOwnPropertySymbols(object);
  45. if (enumerableOnly) symbols = symbols.filter(function (sym) {
  46. return Object.getOwnPropertyDescriptor(object, sym).enumerable;
  47. });
  48. keys.push.apply(keys, symbols);
  49. }
  50. return keys;
  51. }
  52. function _objectSpread2(target) {
  53. for (var i = 1; i < arguments.length; i++) {
  54. var source = arguments[i] != null ? arguments[i] : {};
  55. if (i % 2) {
  56. ownKeys(Object(source), true).forEach(function (key) {
  57. _defineProperty(target, key, source[key]);
  58. });
  59. } else if (Object.getOwnPropertyDescriptors) {
  60. Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
  61. } else {
  62. ownKeys(Object(source)).forEach(function (key) {
  63. Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
  64. });
  65. }
  66. }
  67. return target;
  68. }
  69. /**
  70. * ------------------------------------------------------------------------
  71. * Constants
  72. * ------------------------------------------------------------------------
  73. */
  74. var NAME = 'dropdown';
  75. var VERSION = '4.5.0';
  76. var DATA_KEY = 'bs.dropdown';
  77. var EVENT_KEY = "." + DATA_KEY;
  78. var DATA_API_KEY = '.data-api';
  79. var JQUERY_NO_CONFLICT = $.fn[NAME];
  80. var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key
  81. var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key
  82. var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key
  83. var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key
  84. var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key
  85. var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse)
  86. var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + "|" + ARROW_DOWN_KEYCODE + "|" + ESCAPE_KEYCODE);
  87. var EVENT_HIDE = "hide" + EVENT_KEY;
  88. var EVENT_HIDDEN = "hidden" + EVENT_KEY;
  89. var EVENT_SHOW = "show" + EVENT_KEY;
  90. var EVENT_SHOWN = "shown" + EVENT_KEY;
  91. var EVENT_CLICK = "click" + EVENT_KEY;
  92. var EVENT_CLICK_DATA_API = "click" + EVENT_KEY + DATA_API_KEY;
  93. var EVENT_KEYDOWN_DATA_API = "keydown" + EVENT_KEY + DATA_API_KEY;
  94. var EVENT_KEYUP_DATA_API = "keyup" + EVENT_KEY + DATA_API_KEY;
  95. var CLASS_NAME_DISABLED = 'disabled';
  96. var CLASS_NAME_SHOW = 'show';
  97. var CLASS_NAME_DROPUP = 'dropup';
  98. var CLASS_NAME_DROPRIGHT = 'dropright';
  99. var CLASS_NAME_DROPLEFT = 'dropleft';
  100. var CLASS_NAME_MENURIGHT = 'dropdown-menu-right';
  101. var CLASS_NAME_POSITION_STATIC = 'position-static';
  102. var SELECTOR_DATA_TOGGLE = '[data-toggle="dropdown"]';
  103. var SELECTOR_FORM_CHILD = '.dropdown form';
  104. var SELECTOR_MENU = '.dropdown-menu';
  105. var SELECTOR_NAVBAR_NAV = '.navbar-nav';
  106. var SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';
  107. var PLACEMENT_TOP = 'top-start';
  108. var PLACEMENT_TOPEND = 'top-end';
  109. var PLACEMENT_BOTTOM = 'bottom-start';
  110. var PLACEMENT_BOTTOMEND = 'bottom-end';
  111. var PLACEMENT_RIGHT = 'right-start';
  112. var PLACEMENT_LEFT = 'left-start';
  113. var Default = {
  114. offset: 0,
  115. flip: true,
  116. boundary: 'scrollParent',
  117. reference: 'toggle',
  118. display: 'dynamic',
  119. popperConfig: null
  120. };
  121. var DefaultType = {
  122. offset: '(number|string|function)',
  123. flip: 'boolean',
  124. boundary: '(string|element)',
  125. reference: '(string|element)',
  126. display: 'string',
  127. popperConfig: '(null|object)'
  128. };
  129. /**
  130. * ------------------------------------------------------------------------
  131. * Class Definition
  132. * ------------------------------------------------------------------------
  133. */
  134. var Dropdown = /*#__PURE__*/function () {
  135. function Dropdown(element, config) {
  136. this._element = element;
  137. this._popper = null;
  138. this._config = this._getConfig(config);
  139. this._menu = this._getMenuElement();
  140. this._inNavbar = this._detectNavbar();
  141. this._addEventListeners();
  142. } // Getters
  143. var _proto = Dropdown.prototype;
  144. // Public
  145. _proto.toggle = function toggle() {
  146. if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED)) {
  147. return;
  148. }
  149. var isActive = $(this._menu).hasClass(CLASS_NAME_SHOW);
  150. Dropdown._clearMenus();
  151. if (isActive) {
  152. return;
  153. }
  154. this.show(true);
  155. };
  156. _proto.show = function show(usePopper) {
  157. if (usePopper === void 0) {
  158. usePopper = false;
  159. }
  160. if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || $(this._menu).hasClass(CLASS_NAME_SHOW)) {
  161. return;
  162. }
  163. var relatedTarget = {
  164. relatedTarget: this._element
  165. };
  166. var showEvent = $.Event(EVENT_SHOW, relatedTarget);
  167. var parent = Dropdown._getParentFromElement(this._element);
  168. $(parent).trigger(showEvent);
  169. if (showEvent.isDefaultPrevented()) {
  170. return;
  171. } // Disable totally Popper.js for Dropdown in Navbar
  172. if (!this._inNavbar && usePopper) {
  173. /**
  174. * Check for Popper dependency
  175. * Popper - https://popper.js.org
  176. */
  177. if (typeof Popper === 'undefined') {
  178. throw new TypeError('Bootstrap\'s dropdowns require Popper.js (https://popper.js.org/)');
  179. }
  180. var referenceElement = this._element;
  181. if (this._config.reference === 'parent') {
  182. referenceElement = parent;
  183. } else if (Util.isElement(this._config.reference)) {
  184. referenceElement = this._config.reference; // Check if it's jQuery element
  185. if (typeof this._config.reference.jquery !== 'undefined') {
  186. referenceElement = this._config.reference[0];
  187. }
  188. } // If boundary is not `scrollParent`, then set position to `static`
  189. // to allow the menu to "escape" the scroll parent's boundaries
  190. // https://github.com/twbs/bootstrap/issues/24251
  191. if (this._config.boundary !== 'scrollParent') {
  192. $(parent).addClass(CLASS_NAME_POSITION_STATIC);
  193. }
  194. this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig());
  195. } // If this is a touch-enabled device we add extra
  196. // empty mouseover listeners to the body's immediate children;
  197. // only needed because of broken event delegation on iOS
  198. // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
  199. if ('ontouchstart' in document.documentElement && $(parent).closest(SELECTOR_NAVBAR_NAV).length === 0) {
  200. $(document.body).children().on('mouseover', null, $.noop);
  201. }
  202. this._element.focus();
  203. this._element.setAttribute('aria-expanded', true);
  204. $(this._menu).toggleClass(CLASS_NAME_SHOW);
  205. $(parent).toggleClass(CLASS_NAME_SHOW).trigger($.Event(EVENT_SHOWN, relatedTarget));
  206. };
  207. _proto.hide = function hide() {
  208. if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || !$(this._menu).hasClass(CLASS_NAME_SHOW)) {
  209. return;
  210. }
  211. var relatedTarget = {
  212. relatedTarget: this._element
  213. };
  214. var hideEvent = $.Event(EVENT_HIDE, relatedTarget);
  215. var parent = Dropdown._getParentFromElement(this._element);
  216. $(parent).trigger(hideEvent);
  217. if (hideEvent.isDefaultPrevented()) {
  218. return;
  219. }
  220. if (this._popper) {
  221. this._popper.destroy();
  222. }
  223. $(this._menu).toggleClass(CLASS_NAME_SHOW);
  224. $(parent).toggleClass(CLASS_NAME_SHOW).trigger($.Event(EVENT_HIDDEN, relatedTarget));
  225. };
  226. _proto.dispose = function dispose() {
  227. $.removeData(this._element, DATA_KEY);
  228. $(this._element).off(EVENT_KEY);
  229. this._element = null;
  230. this._menu = null;
  231. if (this._popper !== null) {
  232. this._popper.destroy();
  233. this._popper = null;
  234. }
  235. };
  236. _proto.update = function update() {
  237. this._inNavbar = this._detectNavbar();
  238. if (this._popper !== null) {
  239. this._popper.scheduleUpdate();
  240. }
  241. } // Private
  242. ;
  243. _proto._addEventListeners = function _addEventListeners() {
  244. var _this = this;
  245. $(this._element).on(EVENT_CLICK, function (event) {
  246. event.preventDefault();
  247. event.stopPropagation();
  248. _this.toggle();
  249. });
  250. };
  251. _proto._getConfig = function _getConfig(config) {
  252. config = _objectSpread2(_objectSpread2(_objectSpread2({}, this.constructor.Default), $(this._element).data()), config);
  253. Util.typeCheckConfig(NAME, config, this.constructor.DefaultType);
  254. return config;
  255. };
  256. _proto._getMenuElement = function _getMenuElement() {
  257. if (!this._menu) {
  258. var parent = Dropdown._getParentFromElement(this._element);
  259. if (parent) {
  260. this._menu = parent.querySelector(SELECTOR_MENU);
  261. }
  262. }
  263. return this._menu;
  264. };
  265. _proto._getPlacement = function _getPlacement() {
  266. var $parentDropdown = $(this._element.parentNode);
  267. var placement = PLACEMENT_BOTTOM; // Handle dropup
  268. if ($parentDropdown.hasClass(CLASS_NAME_DROPUP)) {
  269. placement = $(this._menu).hasClass(CLASS_NAME_MENURIGHT) ? PLACEMENT_TOPEND : PLACEMENT_TOP;
  270. } else if ($parentDropdown.hasClass(CLASS_NAME_DROPRIGHT)) {
  271. placement = PLACEMENT_RIGHT;
  272. } else if ($parentDropdown.hasClass(CLASS_NAME_DROPLEFT)) {
  273. placement = PLACEMENT_LEFT;
  274. } else if ($(this._menu).hasClass(CLASS_NAME_MENURIGHT)) {
  275. placement = PLACEMENT_BOTTOMEND;
  276. }
  277. return placement;
  278. };
  279. _proto._detectNavbar = function _detectNavbar() {
  280. return $(this._element).closest('.navbar').length > 0;
  281. };
  282. _proto._getOffset = function _getOffset() {
  283. var _this2 = this;
  284. var offset = {};
  285. if (typeof this._config.offset === 'function') {
  286. offset.fn = function (data) {
  287. data.offsets = _objectSpread2(_objectSpread2({}, data.offsets), _this2._config.offset(data.offsets, _this2._element) || {});
  288. return data;
  289. };
  290. } else {
  291. offset.offset = this._config.offset;
  292. }
  293. return offset;
  294. };
  295. _proto._getPopperConfig = function _getPopperConfig() {
  296. var popperConfig = {
  297. placement: this._getPlacement(),
  298. modifiers: {
  299. offset: this._getOffset(),
  300. flip: {
  301. enabled: this._config.flip
  302. },
  303. preventOverflow: {
  304. boundariesElement: this._config.boundary
  305. }
  306. }
  307. }; // Disable Popper.js if we have a static display
  308. if (this._config.display === 'static') {
  309. popperConfig.modifiers.applyStyle = {
  310. enabled: false
  311. };
  312. }
  313. return _objectSpread2(_objectSpread2({}, popperConfig), this._config.popperConfig);
  314. } // Static
  315. ;
  316. Dropdown._jQueryInterface = function _jQueryInterface(config) {
  317. return this.each(function () {
  318. var data = $(this).data(DATA_KEY);
  319. var _config = typeof config === 'object' ? config : null;
  320. if (!data) {
  321. data = new Dropdown(this, _config);
  322. $(this).data(DATA_KEY, data);
  323. }
  324. if (typeof config === 'string') {
  325. if (typeof data[config] === 'undefined') {
  326. throw new TypeError("No method named \"" + config + "\"");
  327. }
  328. data[config]();
  329. }
  330. });
  331. };
  332. Dropdown._clearMenus = function _clearMenus(event) {
  333. if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) {
  334. return;
  335. }
  336. var toggles = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE));
  337. for (var i = 0, len = toggles.length; i < len; i++) {
  338. var parent = Dropdown._getParentFromElement(toggles[i]);
  339. var context = $(toggles[i]).data(DATA_KEY);
  340. var relatedTarget = {
  341. relatedTarget: toggles[i]
  342. };
  343. if (event && event.type === 'click') {
  344. relatedTarget.clickEvent = event;
  345. }
  346. if (!context) {
  347. continue;
  348. }
  349. var dropdownMenu = context._menu;
  350. if (!$(parent).hasClass(CLASS_NAME_SHOW)) {
  351. continue;
  352. }
  353. if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $.contains(parent, event.target)) {
  354. continue;
  355. }
  356. var hideEvent = $.Event(EVENT_HIDE, relatedTarget);
  357. $(parent).trigger(hideEvent);
  358. if (hideEvent.isDefaultPrevented()) {
  359. continue;
  360. } // If this is a touch-enabled device we remove the extra
  361. // empty mouseover listeners we added for iOS support
  362. if ('ontouchstart' in document.documentElement) {
  363. $(document.body).children().off('mouseover', null, $.noop);
  364. }
  365. toggles[i].setAttribute('aria-expanded', 'false');
  366. if (context._popper) {
  367. context._popper.destroy();
  368. }
  369. $(dropdownMenu).removeClass(CLASS_NAME_SHOW);
  370. $(parent).removeClass(CLASS_NAME_SHOW).trigger($.Event(EVENT_HIDDEN, relatedTarget));
  371. }
  372. };
  373. Dropdown._getParentFromElement = function _getParentFromElement(element) {
  374. var parent;
  375. var selector = Util.getSelectorFromElement(element);
  376. if (selector) {
  377. parent = document.querySelector(selector);
  378. }
  379. return parent || element.parentNode;
  380. } // eslint-disable-next-line complexity
  381. ;
  382. Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) {
  383. // If not input/textarea:
  384. // - And not a key in REGEXP_KEYDOWN => not a dropdown command
  385. // If input/textarea:
  386. // - If space key => not a dropdown command
  387. // - If key is other than escape
  388. // - If key is not up or down => not a dropdown command
  389. // - If trigger inside the menu => not a dropdown command
  390. if (/input|textarea/i.test(event.target.tagName) ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE && (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE || $(event.target).closest(SELECTOR_MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {
  391. return;
  392. }
  393. if (this.disabled || $(this).hasClass(CLASS_NAME_DISABLED)) {
  394. return;
  395. }
  396. var parent = Dropdown._getParentFromElement(this);
  397. var isActive = $(parent).hasClass(CLASS_NAME_SHOW);
  398. if (!isActive && event.which === ESCAPE_KEYCODE) {
  399. return;
  400. }
  401. event.preventDefault();
  402. event.stopPropagation();
  403. if (!isActive || isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {
  404. if (event.which === ESCAPE_KEYCODE) {
  405. $(parent.querySelector(SELECTOR_DATA_TOGGLE)).trigger('focus');
  406. }
  407. $(this).trigger('click');
  408. return;
  409. }
  410. var items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS)).filter(function (item) {
  411. return $(item).is(':visible');
  412. });
  413. if (items.length === 0) {
  414. return;
  415. }
  416. var index = items.indexOf(event.target);
  417. if (event.which === ARROW_UP_KEYCODE && index > 0) {
  418. // Up
  419. index--;
  420. }
  421. if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) {
  422. // Down
  423. index++;
  424. }
  425. if (index < 0) {
  426. index = 0;
  427. }
  428. items[index].focus();
  429. };
  430. _createClass(Dropdown, null, [{
  431. key: "VERSION",
  432. get: function get() {
  433. return VERSION;
  434. }
  435. }, {
  436. key: "Default",
  437. get: function get() {
  438. return Default;
  439. }
  440. }, {
  441. key: "DefaultType",
  442. get: function get() {
  443. return DefaultType;
  444. }
  445. }]);
  446. return Dropdown;
  447. }();
  448. /**
  449. * ------------------------------------------------------------------------
  450. * Data Api implementation
  451. * ------------------------------------------------------------------------
  452. */
  453. $(document).on(EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown._dataApiKeydownHandler).on(EVENT_CLICK_DATA_API + " " + EVENT_KEYUP_DATA_API, Dropdown._clearMenus).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
  454. event.preventDefault();
  455. event.stopPropagation();
  456. Dropdown._jQueryInterface.call($(this), 'toggle');
  457. }).on(EVENT_CLICK_DATA_API, SELECTOR_FORM_CHILD, function (e) {
  458. e.stopPropagation();
  459. });
  460. /**
  461. * ------------------------------------------------------------------------
  462. * jQuery
  463. * ------------------------------------------------------------------------
  464. */
  465. $.fn[NAME] = Dropdown._jQueryInterface;
  466. $.fn[NAME].Constructor = Dropdown;
  467. $.fn[NAME].noConflict = function () {
  468. $.fn[NAME] = JQUERY_NO_CONFLICT;
  469. return Dropdown._jQueryInterface;
  470. };
  471. return Dropdown;
  472. })));
  473. //# sourceMappingURL=dropdown.js.map