From 312b7eaa0c7c075ab042bbe755a3d977f8b5064d Mon Sep 17 00:00:00 2001 From: Maxime Poulin Date: Wed, 25 May 2016 03:41:41 -0400 Subject: [PATCH] Keep chat stickied to the bottom on resize Fixes the chat not staying at the bottom when opening the on-screen keyboard on mobile. --- client/js/libs/jquery/stickyscroll.js | 33 +++++++++++++++++++++------ 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/client/js/libs/jquery/stickyscroll.js b/client/js/libs/jquery/stickyscroll.js index d86740b3..e50b748f 100644 --- a/client/js/libs/jquery/stickyscroll.js +++ b/client/js/libs/jquery/stickyscroll.js @@ -1,29 +1,48 @@ (function($) { $.fn.unsticky = function() { - return this.unbind(".sticky"); + return this.trigger("unstick.sticky").unbind(".sticky"); }; $.fn.sticky = function() { var self = this; var stuckToBottom = true; + var lastStick = 0; + var keepToBottom = function() { + if (stuckToBottom) { + self.scrollBottom(); + } + }; + + $(window).on("resize.sticky", keepToBottom); self - .on("scroll.sticky", function(e) { - stuckToBottom = self.isScrollBottom(); + .on("unstick.sticky", function() { + $(window).off("resize.sticky", keepToBottom); }) - .on("msg.sticky", function() { - if (stuckToBottom) { + .on("scroll.sticky", function() { + // When resizing, sometimes the browser sends a bunch of extra scroll events due to content + // reflow, so if we resized within 250ms we can assume it's one of those. The order of said + // events is not predictable, and scroll can happen last, so not setting stuckToBottom is + // not enough, we have to force the scroll still. + if (stuckToBottom && Date.now() - lastStick < 250) { self.scrollBottom(); + } else { + stuckToBottom = self.isScrollBottom(); } }) + .on("scrollBottom.sticky", function() { + stuckToBottom = true; + lastStick = Date.now(); + this.scrollTop = this.scrollHeight; + }) + .on("msg.sticky", keepToBottom) .scrollBottom(); return self; }; $.fn.scrollBottom = function() { - var el = this[0]; - this.scrollTop(el.scrollHeight); + this.trigger("scrollBottom.sticky"); return this; };