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.

scrollspy.js 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. /*!
  2. * Bootstrap scrollspy.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('./util.js')) :
  8. typeof define === 'function' && define.amd ? define(['jquery', './util.js'], factory) :
  9. (global = global || self, global.ScrollSpy = factory(global.jQuery, global.Util));
  10. }(this, (function ($, Util) { 'use strict';
  11. $ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $;
  12. Util = Util && Object.prototype.hasOwnProperty.call(Util, 'default') ? Util['default'] : Util;
  13. function _defineProperties(target, props) {
  14. for (var i = 0; i < props.length; i++) {
  15. var descriptor = props[i];
  16. descriptor.enumerable = descriptor.enumerable || false;
  17. descriptor.configurable = true;
  18. if ("value" in descriptor) descriptor.writable = true;
  19. Object.defineProperty(target, descriptor.key, descriptor);
  20. }
  21. }
  22. function _createClass(Constructor, protoProps, staticProps) {
  23. if (protoProps) _defineProperties(Constructor.prototype, protoProps);
  24. if (staticProps) _defineProperties(Constructor, staticProps);
  25. return Constructor;
  26. }
  27. function _defineProperty(obj, key, value) {
  28. if (key in obj) {
  29. Object.defineProperty(obj, key, {
  30. value: value,
  31. enumerable: true,
  32. configurable: true,
  33. writable: true
  34. });
  35. } else {
  36. obj[key] = value;
  37. }
  38. return obj;
  39. }
  40. function ownKeys(object, enumerableOnly) {
  41. var keys = Object.keys(object);
  42. if (Object.getOwnPropertySymbols) {
  43. var symbols = Object.getOwnPropertySymbols(object);
  44. if (enumerableOnly) symbols = symbols.filter(function (sym) {
  45. return Object.getOwnPropertyDescriptor(object, sym).enumerable;
  46. });
  47. keys.push.apply(keys, symbols);
  48. }
  49. return keys;
  50. }
  51. function _objectSpread2(target) {
  52. for (var i = 1; i < arguments.length; i++) {
  53. var source = arguments[i] != null ? arguments[i] : {};
  54. if (i % 2) {
  55. ownKeys(Object(source), true).forEach(function (key) {
  56. _defineProperty(target, key, source[key]);
  57. });
  58. } else if (Object.getOwnPropertyDescriptors) {
  59. Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
  60. } else {
  61. ownKeys(Object(source)).forEach(function (key) {
  62. Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
  63. });
  64. }
  65. }
  66. return target;
  67. }
  68. /**
  69. * ------------------------------------------------------------------------
  70. * Constants
  71. * ------------------------------------------------------------------------
  72. */
  73. var NAME = 'scrollspy';
  74. var VERSION = '4.5.0';
  75. var DATA_KEY = 'bs.scrollspy';
  76. var EVENT_KEY = "." + DATA_KEY;
  77. var DATA_API_KEY = '.data-api';
  78. var JQUERY_NO_CONFLICT = $.fn[NAME];
  79. var Default = {
  80. offset: 10,
  81. method: 'auto',
  82. target: ''
  83. };
  84. var DefaultType = {
  85. offset: 'number',
  86. method: 'string',
  87. target: '(string|element)'
  88. };
  89. var EVENT_ACTIVATE = "activate" + EVENT_KEY;
  90. var EVENT_SCROLL = "scroll" + EVENT_KEY;
  91. var EVENT_LOAD_DATA_API = "load" + EVENT_KEY + DATA_API_KEY;
  92. var CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';
  93. var CLASS_NAME_ACTIVE = 'active';
  94. var SELECTOR_DATA_SPY = '[data-spy="scroll"]';
  95. var SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';
  96. var SELECTOR_NAV_LINKS = '.nav-link';
  97. var SELECTOR_NAV_ITEMS = '.nav-item';
  98. var SELECTOR_LIST_ITEMS = '.list-group-item';
  99. var SELECTOR_DROPDOWN = '.dropdown';
  100. var SELECTOR_DROPDOWN_ITEMS = '.dropdown-item';
  101. var SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';
  102. var METHOD_OFFSET = 'offset';
  103. var METHOD_POSITION = 'position';
  104. /**
  105. * ------------------------------------------------------------------------
  106. * Class Definition
  107. * ------------------------------------------------------------------------
  108. */
  109. var ScrollSpy = /*#__PURE__*/function () {
  110. function ScrollSpy(element, config) {
  111. var _this = this;
  112. this._element = element;
  113. this._scrollElement = element.tagName === 'BODY' ? window : element;
  114. this._config = this._getConfig(config);
  115. this._selector = this._config.target + " " + SELECTOR_NAV_LINKS + "," + (this._config.target + " " + SELECTOR_LIST_ITEMS + ",") + (this._config.target + " " + SELECTOR_DROPDOWN_ITEMS);
  116. this._offsets = [];
  117. this._targets = [];
  118. this._activeTarget = null;
  119. this._scrollHeight = 0;
  120. $(this._scrollElement).on(EVENT_SCROLL, function (event) {
  121. return _this._process(event);
  122. });
  123. this.refresh();
  124. this._process();
  125. } // Getters
  126. var _proto = ScrollSpy.prototype;
  127. // Public
  128. _proto.refresh = function refresh() {
  129. var _this2 = this;
  130. var autoMethod = this._scrollElement === this._scrollElement.window ? METHOD_OFFSET : METHOD_POSITION;
  131. var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;
  132. var offsetBase = offsetMethod === METHOD_POSITION ? this._getScrollTop() : 0;
  133. this._offsets = [];
  134. this._targets = [];
  135. this._scrollHeight = this._getScrollHeight();
  136. var targets = [].slice.call(document.querySelectorAll(this._selector));
  137. targets.map(function (element) {
  138. var target;
  139. var targetSelector = Util.getSelectorFromElement(element);
  140. if (targetSelector) {
  141. target = document.querySelector(targetSelector);
  142. }
  143. if (target) {
  144. var targetBCR = target.getBoundingClientRect();
  145. if (targetBCR.width || targetBCR.height) {
  146. // TODO (fat): remove sketch reliance on jQuery position/offset
  147. return [$(target)[offsetMethod]().top + offsetBase, targetSelector];
  148. }
  149. }
  150. return null;
  151. }).filter(function (item) {
  152. return item;
  153. }).sort(function (a, b) {
  154. return a[0] - b[0];
  155. }).forEach(function (item) {
  156. _this2._offsets.push(item[0]);
  157. _this2._targets.push(item[1]);
  158. });
  159. };
  160. _proto.dispose = function dispose() {
  161. $.removeData(this._element, DATA_KEY);
  162. $(this._scrollElement).off(EVENT_KEY);
  163. this._element = null;
  164. this._scrollElement = null;
  165. this._config = null;
  166. this._selector = null;
  167. this._offsets = null;
  168. this._targets = null;
  169. this._activeTarget = null;
  170. this._scrollHeight = null;
  171. } // Private
  172. ;
  173. _proto._getConfig = function _getConfig(config) {
  174. config = _objectSpread2(_objectSpread2({}, Default), typeof config === 'object' && config ? config : {});
  175. if (typeof config.target !== 'string' && Util.isElement(config.target)) {
  176. var id = $(config.target).attr('id');
  177. if (!id) {
  178. id = Util.getUID(NAME);
  179. $(config.target).attr('id', id);
  180. }
  181. config.target = "#" + id;
  182. }
  183. Util.typeCheckConfig(NAME, config, DefaultType);
  184. return config;
  185. };
  186. _proto._getScrollTop = function _getScrollTop() {
  187. return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop;
  188. };
  189. _proto._getScrollHeight = function _getScrollHeight() {
  190. return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
  191. };
  192. _proto._getOffsetHeight = function _getOffsetHeight() {
  193. return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height;
  194. };
  195. _proto._process = function _process() {
  196. var scrollTop = this._getScrollTop() + this._config.offset;
  197. var scrollHeight = this._getScrollHeight();
  198. var maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight();
  199. if (this._scrollHeight !== scrollHeight) {
  200. this.refresh();
  201. }
  202. if (scrollTop >= maxScroll) {
  203. var target = this._targets[this._targets.length - 1];
  204. if (this._activeTarget !== target) {
  205. this._activate(target);
  206. }
  207. return;
  208. }
  209. if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {
  210. this._activeTarget = null;
  211. this._clear();
  212. return;
  213. }
  214. for (var i = this._offsets.length; i--;) {
  215. var isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]);
  216. if (isActiveTarget) {
  217. this._activate(this._targets[i]);
  218. }
  219. }
  220. };
  221. _proto._activate = function _activate(target) {
  222. this._activeTarget = target;
  223. this._clear();
  224. var queries = this._selector.split(',').map(function (selector) {
  225. return selector + "[data-target=\"" + target + "\"]," + selector + "[href=\"" + target + "\"]";
  226. });
  227. var $link = $([].slice.call(document.querySelectorAll(queries.join(','))));
  228. if ($link.hasClass(CLASS_NAME_DROPDOWN_ITEM)) {
  229. $link.closest(SELECTOR_DROPDOWN).find(SELECTOR_DROPDOWN_TOGGLE).addClass(CLASS_NAME_ACTIVE);
  230. $link.addClass(CLASS_NAME_ACTIVE);
  231. } else {
  232. // Set triggered link as active
  233. $link.addClass(CLASS_NAME_ACTIVE); // Set triggered links parents as active
  234. // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
  235. $link.parents(SELECTOR_NAV_LIST_GROUP).prev(SELECTOR_NAV_LINKS + ", " + SELECTOR_LIST_ITEMS).addClass(CLASS_NAME_ACTIVE); // Handle special case when .nav-link is inside .nav-item
  236. $link.parents(SELECTOR_NAV_LIST_GROUP).prev(SELECTOR_NAV_ITEMS).children(SELECTOR_NAV_LINKS).addClass(CLASS_NAME_ACTIVE);
  237. }
  238. $(this._scrollElement).trigger(EVENT_ACTIVATE, {
  239. relatedTarget: target
  240. });
  241. };
  242. _proto._clear = function _clear() {
  243. [].slice.call(document.querySelectorAll(this._selector)).filter(function (node) {
  244. return node.classList.contains(CLASS_NAME_ACTIVE);
  245. }).forEach(function (node) {
  246. return node.classList.remove(CLASS_NAME_ACTIVE);
  247. });
  248. } // Static
  249. ;
  250. ScrollSpy._jQueryInterface = function _jQueryInterface(config) {
  251. return this.each(function () {
  252. var data = $(this).data(DATA_KEY);
  253. var _config = typeof config === 'object' && config;
  254. if (!data) {
  255. data = new ScrollSpy(this, _config);
  256. $(this).data(DATA_KEY, data);
  257. }
  258. if (typeof config === 'string') {
  259. if (typeof data[config] === 'undefined') {
  260. throw new TypeError("No method named \"" + config + "\"");
  261. }
  262. data[config]();
  263. }
  264. });
  265. };
  266. _createClass(ScrollSpy, null, [{
  267. key: "VERSION",
  268. get: function get() {
  269. return VERSION;
  270. }
  271. }, {
  272. key: "Default",
  273. get: function get() {
  274. return Default;
  275. }
  276. }]);
  277. return ScrollSpy;
  278. }();
  279. /**
  280. * ------------------------------------------------------------------------
  281. * Data Api implementation
  282. * ------------------------------------------------------------------------
  283. */
  284. $(window).on(EVENT_LOAD_DATA_API, function () {
  285. var scrollSpys = [].slice.call(document.querySelectorAll(SELECTOR_DATA_SPY));
  286. var scrollSpysLength = scrollSpys.length;
  287. for (var i = scrollSpysLength; i--;) {
  288. var $spy = $(scrollSpys[i]);
  289. ScrollSpy._jQueryInterface.call($spy, $spy.data());
  290. }
  291. });
  292. /**
  293. * ------------------------------------------------------------------------
  294. * jQuery
  295. * ------------------------------------------------------------------------
  296. */
  297. $.fn[NAME] = ScrollSpy._jQueryInterface;
  298. $.fn[NAME].Constructor = ScrollSpy;
  299. $.fn[NAME].noConflict = function () {
  300. $.fn[NAME] = JQUERY_NO_CONFLICT;
  301. return ScrollSpy._jQueryInterface;
  302. };
  303. return ScrollSpy;
  304. })));
  305. //# sourceMappingURL=scrollspy.js.map