aboutsummaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
authorCharles B Johnson <[email protected]>2014-04-24 23:15:38 -0400
committerCharles B Johnson <[email protected]>2014-07-18 10:45:59 -0400
commit8c0eb9b00e28dada2b4aaa3792e89099743c675f (patch)
tree35ce87ee11ca9debe0863a04f376983aa96e25bc /js
parentd3dea01a11436921dac54032c83479ed1e41f6c7 (diff)
downloadbootstrap-8c0eb9b00e28dada2b4aaa3792e89099743c675f.tar.xz
bootstrap-8c0eb9b00e28dada2b4aaa3792e89099743c675f.zip
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.
Diffstat (limited to 'js')
-rw-r--r--js/affix.js63
1 files changed, 45 insertions, 18 deletions
diff --git a/js/affix.js b/js/affix.js
index 26b09db56..daebbffdd 100644
--- a/js/affix.js
+++ b/js/affix.js
@@ -37,6 +37,35 @@
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 () {
if (this.pinnedOffset) return this.pinnedOffset
this.$element.removeClass(Affix.RESET).addClass('affix')
@@ -53,8 +82,7 @@
if (!this.$element.is(':visible')) return
var scrollHeight = $(document).height()
- var scrollTop = this.$target.scrollTop()
- var position = this.$element.offset()
+ var height = this.$element.height()
var offset = this.options.offset
var offsetTop = offset.top
var offsetBottom = offset.bottom
@@ -63,31 +91,30 @@
if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
- var affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? false :
- offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' :
- offsetTop != null && (scrollTop <= offsetTop) ? 'top' : false
+ var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
- if (this.affixed === affix) return
- if (this.unpin != null) this.$element.css('top', '')
+ if (this.affixed != affix) {
+ if (this.unpin != null) this.$element.css('top', '')
- var affixType = 'affix' + (affix ? '-' + affix : '')
- var e = $.Event(affixType + '.bs.affix')
+ var affixType = 'affix' + (affix ? '-' + 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.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
+ this.affixed = affix
+ this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
- this.$element
- .removeClass(Affix.RESET)
- .addClass(affixType)
- .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
+ this.$element
+ .removeClass(Affix.RESET)
+ .addClass(affixType)
+ .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
+ }
if (affix == 'bottom') {
this.$element.offset({
- top: scrollHeight - this.$element.height() - offsetBottom
+ top: scrollHeight - height - offsetBottom
})
}
}