UX: fix jerky UI when creating new posts

- do not scroll screen if post is already on screen
- do not hide/show suggested topics each time you post
- be less aggressive about setting scrollTop in LockOn
This commit is contained in:
Sam
2015-03-05 15:01:17 +11:00
parent b015db647b
commit 5ba5a9f3d6
4 changed files with 76 additions and 25 deletions

View File

@@ -1,3 +1,21 @@
// Dear traveller, you are entering a zone where we are at war with the browser
// the browser is insisting on positioning scrollTop per the location it was in
// the past, we are insisting on it being where we want it to be
// The hack is just to keep trying over and over to positiong the scrollbar (up to 1 minute)
//
// The root cause is that a "refresh" on a topic page will almost never be at the
// same position it was in the past, the URL points to the post at the top of the
// page, so a refresh will try to bring that post into view causing drift
//
// Additionally if you loaded multiple batches of posts, on refresh they will not
// be loaded.
//
// This hack leads to a slight jerky experience, however other workarounds are more
// complex, the 2 options we have are
//
// 1. onbeforeunload ensure we are scrolled to the right spot
// 2. give up on the scrollbar and implement it ourselves (something that will happen)
(function (exports) {
var scrollEvents = "scroll.lock-on touchmove.lock-on mousedown.lock-on wheel.lock-on DOMMouseScroll.lock-on mousewheel.lock-on keyup.lock-on";
@@ -19,11 +37,15 @@
LockOn.prototype.lock = function() {
var self = this,
previousTop = this.elementTop(),
startedAt = new Date().getTime()
startedAt = new Date().getTime(),
i = 0;
$(window).scrollTop(previousTop);
var within = function(threshold,x,y) {
return Math.abs(x-y) < threshold;
};
var interval = setInterval(function() {
i = i + 1;
@@ -31,20 +53,24 @@
scrollTop = $(window).scrollTop();
if (typeof(top) === "undefined") {
$('body,html').off(scrollEvents)
$('body,html').off(scrollEvents);
clearInterval(interval);
return;
}
if ((top !== previousTop) || (scrollTop !== top)) {
if (!within(4, top, previousTop) || !within(4, scrollTop, top)) {
$(window).scrollTop(top);
// animating = true;
// $('html,body').animate({scrollTop: parseInt(top,10)+'px'}, 200, 'swing', function(){
// animating = false;
// });
previousTop = top;
}
// We commit suicide after 1s just to clean up
// We commit suicide after 3s just to clean up
var nowTime = new Date().getTime();
if (nowTime - startedAt > 1000) {
$('body,html').off(scrollEvents)
$('body,html').off(scrollEvents);
clearInterval(interval);
}
@@ -55,7 +81,7 @@
$('body,html').off(scrollEvents);
clearInterval(interval);
}
})
});
};