Skip to content

Instantly share code, notes, and snippets.

@marcustyphoon
Last active August 22, 2020 02:25
Show Gist options
  • Save marcustyphoon/e04d2990d89c5a68b997d5c74dbe059d to your computer and use it in GitHub Desktop.
Save marcustyphoon/e04d2990d89c5a68b997d5c74dbe059d to your computer and use it in GitHub Desktop.
/**
* Preserves the user's scroll location while running a function that modifies post heights in
* real time.
*
* This is done by choosing a point on the screen, picking the nearest post, and restoring
* the position of that post relative to that point, even if it becomes collapsed.
*
* Supplying the element the user clicked to trigger height modification is recommended, as the
* closest post to where they clicked is probably what they expect to stay stationary. If not,
* the center of the viewport is used.
*
* @param {Function} func - the post-modifying function to be run
* @param {JQuery} [$targetElement] - a JQuery object whose position will be the target
*/
preserveScrollPosition: function(func, $targetElement) {
var $fixedPost = null;
const oldPagePosition = $(window).scrollTop();
const targetLocationPage = $targetElement ?
$targetElement.offset().top + $targetElement.outerHeight() / 2 :
oldPagePosition + $(window).height() / 2;
const targetLocationViewport = targetLocationPage - oldPagePosition;
$('[data-id]').each(function() {
if ($(this).offset().top + $(this).outerHeight() > targetLocationPage) {
$fixedPost = $(this);
return false; //breaks each()
}
});
if (!$fixedPost) { func(); return; }
//debug
//$fixedPost.css("outline", "1px solid red");
//$fixedPost.css("outline-offset", "3px");
var offset = targetLocationPage - $fixedPost.offset().top;
func();
//small delay is a hack but I dunno why it doesn't work without it
//maybe it's Tumblr's javascript?
setTimeout(() => {
offset = Math.min(offset, $fixedPost.outerHeight());
const newPagePosition = $fixedPost.offset().top + offset - targetLocationViewport;
if (Math.abs(newPagePosition - $(window).scrollTop()) > 50) {
$(window).scrollTop(Math.max(newPagePosition, 0));
}
}, 200);
},
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment