diff options
author | Alessandro Chitolina <alekitto@gmail.com> | 2017-09-26 11:04:31 +0300 |
---|---|---|
committer | XhmikosR <xhmikosr@gmail.com> | 2019-02-20 23:05:45 +0300 |
commit | 7f08061eca035d8f75651e9c3c32503e91f86fae (patch) | |
tree | 1fcc2e4b252774265df7788359a6d2f509ddd594 /js/src/tab.js | |
parent | 90261b484c7637407b310acecdfe56093738800d (diff) |
rewritten tab without jquery
Diffstat (limited to 'js/src/tab.js')
-rw-r--r-- | js/src/tab.js | 118 |
1 files changed, 56 insertions, 62 deletions
diff --git a/js/src/tab.js b/js/src/tab.js index cb80997afc..9343413480 100644 --- a/js/src/tab.js +++ b/js/src/tab.js @@ -5,7 +5,9 @@ * -------------------------------------------------------------------------- */ -import $ from 'jquery' +import Data from './dom/data' +import EventHandler from './dom/eventHandler' +import SelectorEngine from './dom/selectorEngine' import Util from './util' /** @@ -19,7 +21,6 @@ const VERSION = '4.3.1' const DATA_KEY = 'bs.tab' const EVENT_KEY = `.${DATA_KEY}` const DATA_API_KEY = '.data-api' -const JQUERY_NO_CONFLICT = $.fn[NAME] const Event = { HIDE : `hide${EVENT_KEY}`, @@ -41,10 +42,10 @@ const Selector = { DROPDOWN : '.dropdown', NAV_LIST_GROUP : '.nav, .list-group', ACTIVE : '.active', - ACTIVE_UL : '> li > .active', + ACTIVE_UL : ':scope > li > .active', DATA_TOGGLE : '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]', DROPDOWN_TOGGLE : '.dropdown-toggle', - DROPDOWN_ACTIVE_CHILD : '> .dropdown-menu .active' + DROPDOWN_ACTIVE_CHILD : ':scope > .dropdown-menu .active' } /** @@ -56,6 +57,8 @@ const Selector = { class Tab { constructor(element) { this._element = element + + Data.setData(this._element, DATA_KEY, this) } // Getters @@ -68,39 +71,37 @@ class Tab { show() { if (this._element.parentNode && - this._element.parentNode.nodeType === Node.ELEMENT_NODE && - $(this._element).hasClass(ClassName.ACTIVE) || - $(this._element).hasClass(ClassName.DISABLED)) { + this._element.parentNode.nodeType === Node.ELEMENT_NODE && + this._element.classList.contains(ClassName.ACTIVE) || + this._element.classList.contains(ClassName.DISABLED)) { return } let target let previous - const listElement = $(this._element).closest(Selector.NAV_LIST_GROUP)[0] + const listElement = SelectorEngine.closest(this._element, Selector.NAV_LIST_GROUP) const selector = Util.getSelectorFromElement(this._element) if (listElement) { const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? Selector.ACTIVE_UL : Selector.ACTIVE - previous = $.makeArray($(listElement).find(itemSelector)) + previous = Util.makeArray(SelectorEngine.find(itemSelector, listElement)) previous = previous[previous.length - 1] } - const hideEvent = $.Event(Event.HIDE, { - relatedTarget: this._element - }) - - const showEvent = $.Event(Event.SHOW, { - relatedTarget: previous - }) + let hideEvent = null if (previous) { - $(previous).trigger(hideEvent) + hideEvent = EventHandler.trigger(previous, Event.HIDE, { + relatedTarget: this._element + }) } - $(this._element).trigger(showEvent) + const showEvent = EventHandler.trigger(this._element, Event.SHOW, { + relatedTarget: previous + }) - if (showEvent.isDefaultPrevented() || - hideEvent.isDefaultPrevented()) { + if (showEvent.defaultPrevented || + hideEvent !== null && hideEvent.defaultPrevented) { return } @@ -114,16 +115,12 @@ class Tab { ) const complete = () => { - const hiddenEvent = $.Event(Event.HIDDEN, { + EventHandler.trigger(previous, Event.HIDDEN, { relatedTarget: this._element }) - - const shownEvent = $.Event(Event.SHOWN, { + EventHandler.trigger(this._element, Event.SHOWN, { relatedTarget: previous }) - - $(previous).trigger(hiddenEvent) - $(this._element).trigger(shownEvent) } if (target) { @@ -134,7 +131,7 @@ class Tab { } dispose() { - $.removeData(this._element, DATA_KEY) + Data.removeData(this._element, DATA_KEY) this._element = null } @@ -142,11 +139,13 @@ class Tab { _activate(element, container, callback) { const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') - ? $(container).find(Selector.ACTIVE_UL) - : $(container).children(Selector.ACTIVE) + ? SelectorEngine.find(Selector.ACTIVE_UL, container) + : SelectorEngine.children(container, Selector.ACTIVE) + + const active = activeElements[0] + const isTransitioning = callback && + (active && active.classList.contains(ClassName.FADE)) - const active = activeElements[0] - const isTransitioning = callback && (active && $(active).hasClass(ClassName.FADE)) const complete = () => this._transitionComplete( element, active, @@ -155,10 +154,9 @@ class Tab { if (active && isTransitioning) { const transitionDuration = Util.getTransitionDurationFromElement(active) + active.classList.remove(ClassName.SHOW) - $(active) - .removeClass(ClassName.SHOW) - .one(Util.TRANSITION_END, complete) + EventHandler.one(active, Util.TRANSITION_END, complete) Util.emulateTransitionEnd(active, transitionDuration) } else { complete() @@ -167,14 +165,12 @@ class Tab { _transitionComplete(element, active, callback) { if (active) { - $(active).removeClass(ClassName.ACTIVE) + active.classList.remove(ClassName.ACTIVE) - const dropdownChild = $(active.parentNode).find( - Selector.DROPDOWN_ACTIVE_CHILD - )[0] + const dropdownChild = SelectorEngine.findOne(Selector.DROPDOWN_ACTIVE_CHILD, active.parentNode) if (dropdownChild) { - $(dropdownChild).removeClass(ClassName.ACTIVE) + dropdownChild.classList.remove(ClassName.ACTIVE) } if (active.getAttribute('role') === 'tab') { @@ -182,7 +178,7 @@ class Tab { } } - $(element).addClass(ClassName.ACTIVE) + element.classList.add(ClassName.ACTIVE) if (element.getAttribute('role') === 'tab') { element.setAttribute('aria-selected', true) } @@ -193,13 +189,12 @@ class Tab { element.classList.add(ClassName.SHOW) } - if (element.parentNode && $(element.parentNode).hasClass(ClassName.DROPDOWN_MENU)) { - const dropdownElement = $(element).closest(Selector.DROPDOWN)[0] + if (element.parentNode && element.parentNode.classList.contains(ClassName.DROPDOWN_MENU)) { + const dropdownElement = SelectorEngine.closest(element, Selector.DROPDOWN) if (dropdownElement) { - const dropdownToggleList = [].slice.call(dropdownElement.querySelectorAll(Selector.DROPDOWN_TOGGLE)) - - $(dropdownToggleList).addClass(ClassName.ACTIVE) + Util.makeArray(dropdownElement.querySelectorAll(Selector.DROPDOWN_TOGGLE)) + .forEach((dropdown) => dropdown.classList.add(ClassName.ACTIVE)) } element.setAttribute('aria-expanded', true) @@ -214,13 +209,7 @@ class Tab { static _jQueryInterface(config) { return this.each(function () { - const $this = $(this) - let data = $this.data(DATA_KEY) - - if (!data) { - data = new Tab(this) - $this.data(DATA_KEY, data) - } + const data = Data.getData(this, DATA_KEY) || new Tab(this) if (typeof config === 'string') { if (typeof data[config] === 'undefined') { @@ -238,11 +227,12 @@ class Tab { * ------------------------------------------------------------------------ */ -$(document) - .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { - event.preventDefault() - Tab._jQueryInterface.call($(this), 'show') - }) +EventHandler.on(document, Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { + event.preventDefault() + + const data = Data.getData(this, DATA_KEY) || new Tab(this) + data.show() +}) /** * ------------------------------------------------------------------------ @@ -250,11 +240,15 @@ $(document) * ------------------------------------------------------------------------ */ -$.fn[NAME] = Tab._jQueryInterface -$.fn[NAME].Constructor = Tab -$.fn[NAME].noConflict = () => { - $.fn[NAME] = JQUERY_NO_CONFLICT - return Tab._jQueryInterface +const $ = Util.jQuery +if (typeof $ !== 'undefined') { + const JQUERY_NO_CONFLICT = $.fn[NAME] + $.fn[NAME] = Tab._jQueryInterface + $.fn[NAME].Constructor = Tab + $.fn[NAME].noConflict = () => { + $.fn[NAME] = JQUERY_NO_CONFLICT + return Tab._jQueryInterface + } } export default Tab |