0
0
mirror of https://github.com/twbs/bootstrap.git synced 2025-02-19 16:54:24 +01:00

Refactor determining affix state into a separate expanded method

in order to handle multiple edge cases, specifically when the document
  height is dynamic.
Always reposition an affix that is affixed to the bottom.
This commit is contained in:
Charles B Johnson 2014-04-24 23:15:38 -04:00
parent d3dea01a11
commit 8c0eb9b00e

View File

@ -37,6 +37,35 @@
target: window target: window
} }
Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
var scrollTop = this.$target.scrollTop()
var position = this.$element.offset()
var targetHeight = this.$target.height()
if (offsetTop != null && this.affixed == 'top') return scrollTop >= offsetTop ? false : 'top'
if (this.affixed == 'bottom') {
// Can be affixed to the top, use the unpin value
if (offsetTop != null) {
return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
// Can only ever be pinned or affixed to the bottom, ignore unpin value
} else {
return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
}
} else {
var initializing = this.affixed == null
var colliderTop = initializing ? scrollTop : position.top
var colliderHeight = initializing ? targetHeight : height
if (offsetTop != null && colliderTop <= offsetTop) {
return 'top'
} else if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) {
return 'bottom'
} else {
return false
}
}
}
Affix.prototype.getPinnedOffset = function () { Affix.prototype.getPinnedOffset = function () {
if (this.pinnedOffset) return this.pinnedOffset if (this.pinnedOffset) return this.pinnedOffset
this.$element.removeClass(Affix.RESET).addClass('affix') this.$element.removeClass(Affix.RESET).addClass('affix')
@ -53,8 +82,7 @@
if (!this.$element.is(':visible')) return if (!this.$element.is(':visible')) return
var scrollHeight = $(document).height() var scrollHeight = $(document).height()
var scrollTop = this.$target.scrollTop() var height = this.$element.height()
var position = this.$element.offset()
var offset = this.options.offset var offset = this.options.offset
var offsetTop = offset.top var offsetTop = offset.top
var offsetBottom = offset.bottom var offsetBottom = offset.bottom
@ -63,11 +91,9 @@
if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
var affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? false : var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' :
offsetTop != null && (scrollTop <= offsetTop) ? 'top' : false
if (this.affixed === affix) return if (this.affixed != affix) {
if (this.unpin != null) this.$element.css('top', '') if (this.unpin != null) this.$element.css('top', '')
var affixType = 'affix' + (affix ? '-' + affix : '') var affixType = 'affix' + (affix ? '-' + affix : '')
@ -84,10 +110,11 @@
.removeClass(Affix.RESET) .removeClass(Affix.RESET)
.addClass(affixType) .addClass(affixType)
.trigger(affixType.replace('affix', 'affixed') + '.bs.affix') .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
}
if (affix == 'bottom') { if (affix == 'bottom') {
this.$element.offset({ this.$element.offset({
top: scrollHeight - this.$element.height() - offsetBottom top: scrollHeight - height - offsetBottom
}) })
} }
} }