0
0
mirror of https://github.com/twbs/bootstrap.git synced 2025-01-18 10:52:19 +01:00

Handle multiple zero-offset Scrollspy elements.

When the first two elements in a scrollspy content block have a document
offset of zero (i.e. they're hard against the top of the page),
Scrollspy would switch between them on every scroll event.

This could happen, for example, in a system of nested sections:

```
<section id="animals">
  <section id="dogs">
	Content
  </section>
</section>
```

This ocurred because Scrollspy's check to see if it's at the end of the
array of sections uses `!arr[index]`. This misses the case where
`arr[index]` does exist and is zero.

This commit explicitly checks the array bounds.
This commit is contained in:
Caden Lovelace 2015-01-17 01:14:22 +00:00
parent 984204c39e
commit a1aa0f8afd
2 changed files with 39 additions and 1 deletions

View File

@ -96,7 +96,7 @@
for (i = offsets.length; i--;) {
activeTarget != targets[i]
&& scrollTop >= offsets[i]
&& (!offsets[i + 1] || scrollTop <= offsets[i + 1])
&& (offsets[i + 1] === undefined || scrollTop <= offsets[i + 1])
&& this.activate(targets[i])
}
}

View File

@ -142,6 +142,44 @@ $(function () {
.then(function () { return testElementIsActiveAfterScroll('#li-2', '#div-2') })
})
QUnit.test('should add the active class correctly when there are nested elements at 0 scroll offset', function (assert) {
var times = 0
var done = assert.async()
var navbarHtml = '<nav id="navigation" class="navbar">'
+ '<ul class="nav">'
+ '<li id="li-1"><a href="#div-1">div 1</a>'
+ '<ul>'
+ '<li id="li-2"><a href="#div-2">div 2</a></li>'
+ '</ul>'
+ '</li>'
+ '</ul>'
+ '</nav>'
var contentHtml = '<div class="content" style="position: absolute; top: 0px; overflow: auto; height: 50px">'
+ '<div id="div-1" style="padding: 0; margin: 0">'
+ '<div id="div-2" style="height: 200px; padding: 0; margin: 0">div 2</div>'
+ '</div>'
+ '</div>'
$(navbarHtml).appendTo('#qunit-fixture')
var $content = $(contentHtml)
.appendTo('#qunit-fixture')
.bootstrapScrollspy({ offset: 0, target: '#navigation' })
!function testActiveElements() {
if (++times > 3) return done()
$content.one('scroll', function () {
assert.ok($('#li-1').hasClass('active'), 'nav item for outer element has "active" class')
assert.ok($('#li-2').hasClass('active'), 'nav item for inner element has "active" class')
testActiveElements()
})
$content.scrollTop($content.scrollTop() + 10)
}()
})
QUnit.test('should clear selection if above the first section', function (assert) {
var done = assert.async()