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.

button.js 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /**
  2. * --------------------------------------------------------------------------
  3. * Bootstrap (v4.5.0): button.js
  4. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  5. * --------------------------------------------------------------------------
  6. */
  7. import $ from 'jquery'
  8. /**
  9. * ------------------------------------------------------------------------
  10. * Constants
  11. * ------------------------------------------------------------------------
  12. */
  13. const NAME = 'button'
  14. const VERSION = '4.5.0'
  15. const DATA_KEY = 'bs.button'
  16. const EVENT_KEY = `.${DATA_KEY}`
  17. const DATA_API_KEY = '.data-api'
  18. const JQUERY_NO_CONFLICT = $.fn[NAME]
  19. const CLASS_NAME_ACTIVE = 'active'
  20. const CLASS_NAME_BUTTON = 'btn'
  21. const CLASS_NAME_FOCUS = 'focus'
  22. const SELECTOR_DATA_TOGGLE_CARROT = '[data-toggle^="button"]'
  23. const SELECTOR_DATA_TOGGLES = '[data-toggle="buttons"]'
  24. const SELECTOR_DATA_TOGGLE = '[data-toggle="button"]'
  25. const SELECTOR_DATA_TOGGLES_BUTTONS = '[data-toggle="buttons"] .btn'
  26. const SELECTOR_INPUT = 'input:not([type="hidden"])'
  27. const SELECTOR_ACTIVE = '.active'
  28. const SELECTOR_BUTTON = '.btn'
  29. const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
  30. const EVENT_FOCUS_BLUR_DATA_API = `focus${EVENT_KEY}${DATA_API_KEY} ` +
  31. `blur${EVENT_KEY}${DATA_API_KEY}`
  32. const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`
  33. /**
  34. * ------------------------------------------------------------------------
  35. * Class Definition
  36. * ------------------------------------------------------------------------
  37. */
  38. class Button {
  39. constructor(element) {
  40. this._element = element
  41. }
  42. // Getters
  43. static get VERSION() {
  44. return VERSION
  45. }
  46. // Public
  47. toggle() {
  48. let triggerChangeEvent = true
  49. let addAriaPressed = true
  50. const rootElement = $(this._element).closest(
  51. SELECTOR_DATA_TOGGLES
  52. )[0]
  53. if (rootElement) {
  54. const input = this._element.querySelector(SELECTOR_INPUT)
  55. if (input) {
  56. if (input.type === 'radio') {
  57. if (input.checked &&
  58. this._element.classList.contains(CLASS_NAME_ACTIVE)) {
  59. triggerChangeEvent = false
  60. } else {
  61. const activeElement = rootElement.querySelector(SELECTOR_ACTIVE)
  62. if (activeElement) {
  63. $(activeElement).removeClass(CLASS_NAME_ACTIVE)
  64. }
  65. }
  66. }
  67. if (triggerChangeEvent) {
  68. // if it's not a radio button or checkbox don't add a pointless/invalid checked property to the input
  69. if (input.type === 'checkbox' || input.type === 'radio') {
  70. input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE)
  71. }
  72. $(input).trigger('change')
  73. }
  74. input.focus()
  75. addAriaPressed = false
  76. }
  77. }
  78. if (!(this._element.hasAttribute('disabled') || this._element.classList.contains('disabled'))) {
  79. if (addAriaPressed) {
  80. this._element.setAttribute('aria-pressed',
  81. !this._element.classList.contains(CLASS_NAME_ACTIVE))
  82. }
  83. if (triggerChangeEvent) {
  84. $(this._element).toggleClass(CLASS_NAME_ACTIVE)
  85. }
  86. }
  87. }
  88. dispose() {
  89. $.removeData(this._element, DATA_KEY)
  90. this._element = null
  91. }
  92. // Static
  93. static _jQueryInterface(config) {
  94. return this.each(function () {
  95. let data = $(this).data(DATA_KEY)
  96. if (!data) {
  97. data = new Button(this)
  98. $(this).data(DATA_KEY, data)
  99. }
  100. if (config === 'toggle') {
  101. data[config]()
  102. }
  103. })
  104. }
  105. }
  106. /**
  107. * ------------------------------------------------------------------------
  108. * Data Api implementation
  109. * ------------------------------------------------------------------------
  110. */
  111. $(document)
  112. .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, (event) => {
  113. let button = event.target
  114. const initialButton = button
  115. if (!$(button).hasClass(CLASS_NAME_BUTTON)) {
  116. button = $(button).closest(SELECTOR_BUTTON)[0]
  117. }
  118. if (!button || button.hasAttribute('disabled') || button.classList.contains('disabled')) {
  119. event.preventDefault() // work around Firefox bug #1540995
  120. } else {
  121. const inputBtn = button.querySelector(SELECTOR_INPUT)
  122. if (inputBtn && (inputBtn.hasAttribute('disabled') || inputBtn.classList.contains('disabled'))) {
  123. event.preventDefault() // work around Firefox bug #1540995
  124. return
  125. }
  126. if (initialButton.tagName === 'LABEL' && inputBtn && inputBtn.type === 'checkbox') {
  127. event.preventDefault() // work around event sent to label and input
  128. }
  129. Button._jQueryInterface.call($(button), 'toggle')
  130. }
  131. })
  132. .on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, (event) => {
  133. const button = $(event.target).closest(SELECTOR_BUTTON)[0]
  134. $(button).toggleClass(CLASS_NAME_FOCUS, /^focus(in)?$/.test(event.type))
  135. })
  136. $(window).on(EVENT_LOAD_DATA_API, () => {
  137. // ensure correct active class is set to match the controls' actual values/states
  138. // find all checkboxes/readio buttons inside data-toggle groups
  139. let buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLES_BUTTONS))
  140. for (let i = 0, len = buttons.length; i < len; i++) {
  141. const button = buttons[i]
  142. const input = button.querySelector(SELECTOR_INPUT)
  143. if (input.checked || input.hasAttribute('checked')) {
  144. button.classList.add(CLASS_NAME_ACTIVE)
  145. } else {
  146. button.classList.remove(CLASS_NAME_ACTIVE)
  147. }
  148. }
  149. // find all button toggles
  150. buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))
  151. for (let i = 0, len = buttons.length; i < len; i++) {
  152. const button = buttons[i]
  153. if (button.getAttribute('aria-pressed') === 'true') {
  154. button.classList.add(CLASS_NAME_ACTIVE)
  155. } else {
  156. button.classList.remove(CLASS_NAME_ACTIVE)
  157. }
  158. }
  159. })
  160. /**
  161. * ------------------------------------------------------------------------
  162. * jQuery
  163. * ------------------------------------------------------------------------
  164. */
  165. $.fn[NAME] = Button._jQueryInterface
  166. $.fn[NAME].Constructor = Button
  167. $.fn[NAME].noConflict = () => {
  168. $.fn[NAME] = JQUERY_NO_CONFLICT
  169. return Button._jQueryInterface
  170. }
  171. export default Button