Commit 8c0eb9b0 authored by Charles B Johnson's avatar Charles B Johnson

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.
parent d3dea01a
...@@ -37,6 +37,35 @@ ...@@ -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 @@ ...@@ -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,31 +91,30 @@ ...@@ -63,31 +91,30 @@
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 : '')
var e = $.Event(affixType + '.bs.affix') var e = $.Event(affixType + '.bs.affix')
this.$element.trigger(e) this.$element.trigger(e)
if (e.isDefaultPrevented()) return if (e.isDefaultPrevented()) return
this.affixed = affix this.affixed = affix
this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
this.$element this.$element
.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
}) })
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment