Further tweaks to viewport shuffling and dynamic image loading

@BenLubar
This commit is contained in:
Julian Lam
2016-03-30 18:10:03 -04:00
parent 8ae2afff05
commit 1385d19f64
3 changed files with 73 additions and 66 deletions

View File

@@ -10,7 +10,9 @@ define('forum/topic/posts', [
'components'
], function(pagination, infinitescroll, postTools, navigator, components) {
var Posts = {};
var Posts = {
_imageLoaderTimeout: undefined
};
Posts.onNewPost = function(data) {
if (!data || !data.posts || !data.posts.length) {
@@ -240,70 +242,74 @@ define('forum/topic/posts', [
images.each(function() {
$(this).attr('data-src', $(this).attr('src'));
$(this).attr('data-state', 'unloaded');
$(this).attr('src', 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7');
$(this).attr('src', 'about:blank');
});
$(window).scrollTop(scrollTop + $(document).height() - height);
};
Posts.loadImages = function(threshold) {
/*
If threshold is defined, images loaded above this threshold will modify
the user's scroll position so they are not scrolled away from content
they were reading. Images loaded below this threshold will push down content.
if (Posts._imageLoaderTimeout) {
clearTimeout(Posts._imageLoaderTimeout);
}
If no threshold is defined, loaded images will push down content, as per
default
*/
Posts._imageLoaderTimeout = setTimeout(function() {
/*
If threshold is defined, images loaded above this threshold will modify
the user's scroll position so they are not scrolled away from content
they were reading. Images loaded below this threshold will push down content.
var images = components.get('post/content').find('img[data-state="unloaded"]'),
visible = images.filter(function() {
return utils.isElementInViewport(this);
}),
scrollTop = $(window).scrollTop(),
adjusting = false,
adjustQueue = [],
adjustPosition = function() {
adjusting = true;
oldHeight = document.body.clientHeight;
If no threshold is defined, loaded images will push down content, as per
default
*/
// Display the image
$(this).attr('data-state', 'loaded');
newHeight = document.body.clientHeight;
var images = components.get('post/content').find('img[data-state="unloaded"]'),
visible = images.filter(function() {
return utils.isElementInViewport(this);
}),
scrollTop = $(window).scrollTop(),
adjusting = false,
adjustQueue = [],
adjustPosition = function() {
adjusting = true;
oldHeight = document.body.clientHeight;
var imageRect = this.getBoundingClientRect();
if (imageRect.top < threshold) {
scrollTop = scrollTop + (newHeight - oldHeight);
$(window).scrollTop(scrollTop);
}
if (adjustQueue.length) {
adjustQueue.pop()();
} else {
adjusting = false;
}
},
oldHeight, newHeight;
// For each image, reset the source and adjust scrollTop when loaded
visible.attr('data-state', 'loading');
visible.each(function(index, image) {
image = $(image);
image.on('load', function() {
if (!adjusting) {
adjustPosition.call(this);
} else {
adjustQueue.push(adjustPosition.bind(this));
// Display the image
$(this).attr('data-state', 'loaded');
newHeight = document.body.clientHeight;
var imageRect = this.getBoundingClientRect();
if (imageRect.top < threshold) {
scrollTop = scrollTop + (newHeight - oldHeight);
$(window).scrollTop(scrollTop);
}
if (adjustQueue.length) {
adjustQueue.pop()();
} else {
adjusting = false;
}
},
oldHeight, newHeight;
// For each image, reset the source and adjust scrollTop when loaded
visible.attr('data-state', 'loading');
visible.each(function(index, image) {
image = $(image);
image.on('load', function() {
if (!adjusting) {
adjustPosition.call(this);
} else {
adjustQueue.push(adjustPosition.bind(this));
}
});
image.attr('src', image.attr('data-src'));
if (image.parent().attr('href')) {
image.parent().attr('href', image.attr('data-src'));
}
image.removeAttr('data-src');
});
image.attr('src', image.attr('data-src'));
if (image.parent().attr('href')) {
image.parent().attr('href', image.attr('data-src'));
}
image.removeAttr('data-src');
});
}, 250);
};
Posts.wrapImagesInLinks = function(posts) {
@@ -318,13 +324,10 @@ define('forum/topic/posts', [
Posts.showBottomPostBar = function() {
var mainPost = components.get('post', 'index', 0);
var posts = $('[component="post"]');
var height = $(document).height();
if (!!mainPost.length && posts.length > 1 && $('.post-bar').length < 2) {
$('.post-bar').clone().appendTo(mainPost);
$(window).scrollTop($(window).scrollTop() + $(document).height() - height);
} else if (mainPost.length && posts.length < 2) {
mainPost.find('.post-bar').remove();
$(window).scrollTop($(window).scrollTop() - $(document).height() - height);
}
};