Last active
August 22, 2020 02:25
-
-
Save marcustyphoon/e04d2990d89c5a68b997d5c74dbe059d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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