Skip to content

Commit f94f497

Browse files
GeoSotmdo
authored andcommitted
ScrollSpy: Make Proper use of the SelectorEngine
* avoid extra work, creating ids * simplify selectors and constrain search inside `config.target`
1 parent a816615 commit f94f497

File tree

2 files changed

+8
-36
lines changed

2 files changed

+8
-36
lines changed

js/src/scrollspy.js

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@
77

88
import {
99
defineJQueryPlugin,
10+
getElement,
1011
getSelectorFromElement,
11-
getUID,
12-
isElement,
1312
typeCheckConfig
1413
} from './util/index'
1514
import EventHandler from './dom/event-handler'
@@ -52,6 +51,7 @@ const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'
5251
const SELECTOR_NAV_LINKS = '.nav-link'
5352
const SELECTOR_NAV_ITEMS = '.nav-item'
5453
const SELECTOR_LIST_ITEMS = '.list-group-item'
54+
const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}, .${CLASS_NAME_DROPDOWN_ITEM}`
5555
const SELECTOR_DROPDOWN = '.dropdown'
5656
const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'
5757

@@ -69,7 +69,6 @@ class ScrollSpy extends BaseComponent {
6969
super(element)
7070
this._scrollElement = this._element.tagName === 'BODY' ? window : this._element
7171
this._config = this._getConfig(config)
72-
this._selector = `${this._config.target} ${SELECTOR_NAV_LINKS}, ${this._config.target} ${SELECTOR_LIST_ITEMS}, ${this._config.target} .${CLASS_NAME_DROPDOWN_ITEM}`
7372
this._offsets = []
7473
this._targets = []
7574
this._activeTarget = null
@@ -110,7 +109,7 @@ class ScrollSpy extends BaseComponent {
110109
this._targets = []
111110
this._scrollHeight = this._getScrollHeight()
112111

113-
const targets = SelectorEngine.find(this._selector)
112+
const targets = SelectorEngine.find(SELECTOR_LINK_ITEMS, this._config.target)
114113

115114
targets.map(element => {
116115
const targetSelector = getSelectorFromElement(element)
@@ -150,15 +149,7 @@ class ScrollSpy extends BaseComponent {
150149
...(typeof config === 'object' && config ? config : {})
151150
}
152151

153-
if (typeof config.target !== 'string' && isElement(config.target)) {
154-
let { id } = config.target
155-
if (!id) {
156-
id = getUID(NAME)
157-
config.target.id = id
158-
}
159-
160-
config.target = `#${id}`
161-
}
152+
config.target = getElement(config.target) || document.documentElement
162153

163154
typeCheckConfig(NAME, config, DefaultType)
164155

@@ -225,20 +216,16 @@ class ScrollSpy extends BaseComponent {
225216

226217
this._clear()
227218

228-
const queries = this._selector.split(',')
219+
const queries = SELECTOR_LINK_ITEMS.split(',')
229220
.map(selector => `${selector}[data-bs-target="${target}"],${selector}[href="${target}"]`)
230221

231-
const link = SelectorEngine.findOne(queries.join(','))
222+
const link = SelectorEngine.findOne(queries.join(','), this._config.target)
232223

224+
link.classList.add(CLASS_NAME_ACTIVE)
233225
if (link.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {
234226
SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE, link.closest(SELECTOR_DROPDOWN))
235227
.classList.add(CLASS_NAME_ACTIVE)
236-
237-
link.classList.add(CLASS_NAME_ACTIVE)
238228
} else {
239-
// Set triggered link as active
240-
link.classList.add(CLASS_NAME_ACTIVE)
241-
242229
SelectorEngine.parents(link, SELECTOR_NAV_LIST_GROUP)
243230
.forEach(listGroup => {
244231
// Set triggered links parents as active
@@ -261,7 +248,7 @@ class ScrollSpy extends BaseComponent {
261248
}
262249

263250
_clear() {
264-
SelectorEngine.find(this._selector)
251+
SelectorEngine.find(SELECTOR_LINK_ITEMS, this._config.target)
265252
.filter(node => node.classList.contains(CLASS_NAME_ACTIVE))
266253
.forEach(node => node.classList.remove(CLASS_NAME_ACTIVE))
267254
}

js/tests/unit/scrollspy.spec.js

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -65,21 +65,6 @@ describe('ScrollSpy', () => {
6565
expect(sSpyByElement._element).toEqual(sSpyEl)
6666
})
6767

68-
it('should generate an id when there is not one', () => {
69-
fixtureEl.innerHTML = [
70-
'<nav></nav>',
71-
'<div class="content"></div>'
72-
].join('')
73-
74-
const navEl = fixtureEl.querySelector('nav')
75-
const scrollSpy = new ScrollSpy(fixtureEl.querySelector('.content'), {
76-
target: navEl
77-
})
78-
79-
expect(scrollSpy).toBeDefined()
80-
expect(navEl.getAttribute('id')).not.toEqual(null)
81-
})
82-
8368
it('should not process element without target', () => {
8469
fixtureEl.innerHTML = [
8570
'<nav id="navigation" class="navbar">',

0 commit comments

Comments
 (0)