1
0
mirror of https://github.com/twbs/bootstrap.git synced 2025-08-12 16:44:17 +02:00

Revamp Scrollspy using Intersection observer (#33421)

* Revamp scrollspy to use IntersectionObserver

* Add smooth scroll support

* Update scrollspy.js/md

* move functionality to method

* Update scrollspy.js

* Add SmoothScroll to docs example

* Refactor Using `Maps` and smaller methods

* Update scrollspy.md/js

* Update scrollspy.spec.js

* Support backwards compatibility

* minor optimizations

* Merge activation functionality

* Update scrollspy.md

* Update scrollspy.js

* Rewording some of the documentation changes

* Update scrollspy.js

* Update scrollspy.md

* tweaking calculation functionality & drop text that suggests, to deactivate target when wrapper is not visible

* tweak calculation

* Fix lint

* Support scrollspy in body & tests

* change doc example to a more valid solution

Co-authored-by: XhmikosR <xhmikosr@gmail.com>
Co-authored-by: Patrick H. Lauke <redux@splintered.co.uk>
This commit is contained in:
GeoSot
2022-04-13 20:29:13 +03:00
committed by GitHub
parent cfd2f3f778
commit ece1601227
7 changed files with 666 additions and 519 deletions

View File

@@ -105,86 +105,4 @@ describe('Manipulator', () => {
expect(Manipulator.getDataAttribute(div, 'test')).toEqual(1)
})
})
describe('offset', () => {
it('should return an object with two properties top and left, both numbers', () => {
fixtureEl.innerHTML = '<div></div>'
const div = fixtureEl.querySelector('div')
const offset = Manipulator.offset(div)
expect(offset).toBeDefined()
expect(offset.top).toEqual(jasmine.any(Number))
expect(offset.left).toEqual(jasmine.any(Number))
})
it('should return offset relative to attached element\'s offset', () => {
const top = 500
const left = 1000
fixtureEl.innerHTML = `<div style="position:absolute;top:${top}px;left:${left}px"></div>`
const div = fixtureEl.querySelector('div')
const offset = Manipulator.offset(div)
const fixtureOffset = Manipulator.offset(fixtureEl)
expect(offset).toEqual({
top: fixtureOffset.top + top,
left: fixtureOffset.left + left
})
})
it('should not change offset when viewport is scrolled', () => {
return new Promise(resolve => {
const top = 500
const left = 1000
const scrollY = 200
const scrollX = 400
fixtureEl.innerHTML = `<div style="position:absolute;top:${top}px;left:${left}px"></div>`
const div = fixtureEl.querySelector('div')
const offset = Manipulator.offset(div)
// append an element that forces scrollbars on the window so we can scroll
const { defaultView: win, body } = fixtureEl.ownerDocument
const forceScrollBars = document.createElement('div')
forceScrollBars.style.cssText = 'position:absolute;top:5000px;left:5000px;width:1px;height:1px'
body.append(forceScrollBars)
const scrollHandler = () => {
expect(window.pageYOffset).toEqual(scrollY)
expect(window.pageXOffset).toEqual(scrollX)
const newOffset = Manipulator.offset(div)
expect(newOffset).toEqual({
top: offset.top,
left: offset.left
})
win.removeEventListener('scroll', scrollHandler)
forceScrollBars.remove()
win.scrollTo(0, 0)
resolve()
}
win.addEventListener('scroll', scrollHandler)
win.scrollTo(scrollX, scrollY)
})
})
})
describe('position', () => {
it('should return an object with two properties top and left, both numbers', () => {
fixtureEl.innerHTML = '<div></div>'
const div = fixtureEl.querySelector('div')
const position = Manipulator.position(div)
expect(position).toBeDefined()
expect(position.top).toEqual(jasmine.any(Number))
expect(position.left).toEqual(jasmine.any(Number))
})
})
})