use get selector from element only when needed

This commit is contained in:
Johann-S 2019-07-23 21:15:00 +02:00
parent f4dbffe93a
commit fc02932946
8 changed files with 82 additions and 49 deletions

View File

@ -9,7 +9,7 @@ import {
jQuery as $, jQuery as $,
TRANSITION_END, TRANSITION_END,
emulateTransitionEnd, emulateTransitionEnd,
getSelectorFromElement, getElementFromSelector,
getTransitionDurationFromElement getTransitionDurationFromElement
} from '../util/index' } from '../util/index'
import Data from '../dom/data' import Data from '../dom/data'
@ -90,12 +90,7 @@ class Alert {
// Private // Private
_getRootElement(element) { _getRootElement(element) {
const selector = getSelectorFromElement(element) let parent = getElementFromSelector(element)
let parent = false
if (selector) {
parent = SelectorEngine.findOne(selector)
}
if (!parent) { if (!parent) {
parent = SelectorEngine.closest(element, `.${ClassName.ALERT}`) parent = SelectorEngine.closest(element, `.${ClassName.ALERT}`)

View File

@ -9,7 +9,7 @@ import {
jQuery as $, jQuery as $,
TRANSITION_END, TRANSITION_END,
emulateTransitionEnd, emulateTransitionEnd,
getSelectorFromElement, getElementFromSelector,
getTransitionDurationFromElement, getTransitionDurationFromElement,
isVisible, isVisible,
makeArray, makeArray,
@ -569,13 +569,7 @@ class Carousel {
} }
static _dataApiClickHandler(event) { static _dataApiClickHandler(event) {
const selector = getSelectorFromElement(this) const target = getElementFromSelector(this)
if (!selector) {
return
}
const target = SelectorEngine.findOne(selector)
if (!target || !target.classList.contains(ClassName.CAROUSEL)) { if (!target || !target.classList.contains(ClassName.CAROUSEL)) {
return return

View File

@ -10,6 +10,7 @@ import {
TRANSITION_END, TRANSITION_END,
emulateTransitionEnd, emulateTransitionEnd,
getSelectorFromElement, getSelectorFromElement,
getElementFromSelector,
getTransitionDurationFromElement, getTransitionDurationFromElement,
isElement, isElement,
makeArray, makeArray,
@ -244,15 +245,11 @@ class Collapse {
if (triggerArrayLength > 0) { if (triggerArrayLength > 0) {
for (let i = 0; i < triggerArrayLength; i++) { for (let i = 0; i < triggerArrayLength; i++) {
const trigger = this._triggerArray[i] const trigger = this._triggerArray[i]
const selector = getSelectorFromElement(trigger) const elem = getElementFromSelector(trigger)
if (selector !== null) { if (elem && !elem.classList.contains(ClassName.SHOW)) {
const elem = SelectorEngine.findOne(selector) trigger.classList.add(ClassName.COLLAPSED)
trigger.setAttribute('aria-expanded', false)
if (!elem.classList.contains(ClassName.SHOW)) {
trigger.classList.add(ClassName.COLLAPSED)
trigger.setAttribute('aria-expanded', false)
}
} }
} }
} }
@ -320,8 +317,7 @@ class Collapse {
makeArray(SelectorEngine.find(selector, parent)) makeArray(SelectorEngine.find(selector, parent))
.forEach(element => { .forEach(element => {
const selector = getSelectorFromElement(element) const selected = getElementFromSelector(element)
const selected = selector ? SelectorEngine.findOne(selector) : null
this._addAriaAndCollapsedClass( this._addAriaAndCollapsedClass(
selected, selected,

View File

@ -7,7 +7,7 @@
import { import {
jQuery as $, jQuery as $,
getSelectorFromElement, getElementFromSelector,
isElement, isElement,
makeArray, makeArray,
noop, noop,
@ -442,14 +442,7 @@ class Dropdown {
} }
static _getParentFromElement(element) { static _getParentFromElement(element) {
let parent return getElementFromSelector(element) || element.parentNode
const selector = getSelectorFromElement(element)
if (selector) {
parent = SelectorEngine.findOne(selector)
}
return parent || element.parentNode
} }
static _dataApiKeydownHandler(event) { static _dataApiKeydownHandler(event) {

View File

@ -9,7 +9,7 @@ import {
jQuery as $, jQuery as $,
TRANSITION_END, TRANSITION_END,
emulateTransitionEnd, emulateTransitionEnd,
getSelectorFromElement, getElementFromSelector,
getTransitionDurationFromElement, getTransitionDurationFromElement,
isVisible, isVisible,
makeArray, makeArray,
@ -549,8 +549,7 @@ class Modal {
*/ */
EventHandler.on(document, Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { EventHandler.on(document, Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
const selector = getSelectorFromElement(this) const target = getElementFromSelector(this)
const target = SelectorEngine.findOne(selector)
if (this.tagName === 'A' || this.tagName === 'AREA') { if (this.tagName === 'A' || this.tagName === 'AREA') {
event.preventDefault() event.preventDefault()

View File

@ -9,7 +9,7 @@ import {
jQuery as $, jQuery as $,
TRANSITION_END, TRANSITION_END,
emulateTransitionEnd, emulateTransitionEnd,
getSelectorFromElement, getElementFromSelector,
getTransitionDurationFromElement, getTransitionDurationFromElement,
makeArray, makeArray,
reflow reflow
@ -85,10 +85,9 @@ class Tab {
return return
} }
let target
let previous let previous
const target = getElementFromSelector(this._element)
const listElement = SelectorEngine.closest(this._element, Selector.NAV_LIST_GROUP) const listElement = SelectorEngine.closest(this._element, Selector.NAV_LIST_GROUP)
const selector = getSelectorFromElement(this._element)
if (listElement) { if (listElement) {
const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? Selector.ACTIVE_UL : Selector.ACTIVE const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? Selector.ACTIVE_UL : Selector.ACTIVE
@ -113,10 +112,6 @@ class Tab {
return return
} }
if (selector) {
target = SelectorEngine.findOne(selector)
}
this._activate( this._activate(
this._element, this._element,
listElement listElement

View File

@ -28,20 +28,32 @@ const getUID = prefix => {
return prefix return prefix
} }
const getSelectorFromElement = element => { const getSelector = element => {
let selector = element.getAttribute('data-target') let selector = element.getAttribute('data-target')
if (!selector || selector === '#') { if (!selector || selector === '#') {
const hrefAttr = element.getAttribute('href') const hrefAttr = element.getAttribute('href')
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : '' selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null
} }
try { return selector
}
const getSelectorFromElement = element => {
const selector = getSelector(element)
if (selector) {
return document.querySelector(selector) ? selector : null return document.querySelector(selector) ? selector : null
} catch (error) {
return null
} }
return null
}
const getElementFromSelector = element => {
const selector = getSelector(element)
return selector ? document.querySelector(selector) : null
} }
const getTransitionDurationFromElement = element => { const getTransitionDurationFromElement = element => {
@ -169,6 +181,7 @@ export {
TRANSITION_END, TRANSITION_END,
getUID, getUID,
getSelectorFromElement, getSelectorFromElement,
getElementFromSelector,
getTransitionDurationFromElement, getTransitionDurationFromElement,
triggerTransitionEnd, triggerTransitionEnd,
isElement, isElement,

View File

@ -64,6 +64,54 @@ describe('Util', () => {
expect(Util.getSelectorFromElement(testEl)).toBeNull() expect(Util.getSelectorFromElement(testEl)).toBeNull()
}) })
it('should return null if no selector', () => {
fixtureEl.innerHTML = '<div></div>'
const testEl = fixtureEl.querySelector('div')
expect(Util.getSelectorFromElement(testEl)).toBeNull()
})
})
describe('getElementFromSelector', () => {
it('should get element from data-target', () => {
fixtureEl.innerHTML = [
'<div id="test" data-target=".target"></div>',
'<div class="target"></div>'
].join('')
const testEl = fixtureEl.querySelector('#test')
expect(Util.getElementFromSelector(testEl)).toEqual(fixtureEl.querySelector('.target'))
})
it('should get element from href if no data-target set', () => {
fixtureEl.innerHTML = [
'<a id="test" href=".target"></a>',
'<div class="target"></div>'
].join('')
const testEl = fixtureEl.querySelector('#test')
expect(Util.getElementFromSelector(testEl)).toEqual(fixtureEl.querySelector('.target'))
})
it('should return null if element not found', () => {
fixtureEl.innerHTML = '<a id="test" href=".target"></a>'
const testEl = fixtureEl.querySelector('#test')
expect(Util.getElementFromSelector(testEl)).toBeNull()
})
it('should return null if no selector', () => {
fixtureEl.innerHTML = '<div></div>'
const testEl = fixtureEl.querySelector('div')
expect(Util.getElementFromSelector(testEl)).toBeNull()
})
}) })
describe('getTransitionDurationFromElement', () => { describe('getTransitionDurationFromElement', () => {