But then, now every time scroll, it will trigger many requests on loadAnotherArticle(). To prevent it, add a loading flag…
1 2 3 4 5 6 7 8 9 10 11 12 13
// to prevent multiple requests on same article var loading = false;
$(window).scroll(function () { // this is for before reach the bottom-most, it trigger to load next article let offsetPrefix = 500;
if ($(document).height() - $(this).height() - offsetPrefix < $(this).scrollTop()) { if (!loading) { loadAnotherArticle(); } } });
What if want to change the URL & meta title/description when scroll to next article?
1 2 3 4 5 6 7 8 9 10
// helper function to update the meta content functionupdateMeta (item) { window.history.replaceState(item, item.title, item.url); document.title = item.title; $('meta[name="description"]').attr('content', item.description); $('meta[name="og:title"]').attr('content', item.og_title); $('meta[name="og:description"]').attr('content', item.og_description); $('meta[property="og:image"]').attr('content', item.image); $('meta[property="og:url"]').attr('content', item.url); };
The tricky part comes, what URL should be used if in the middle of 1st & 2nd article? Here what I do is, determined by the visible area, which every is higher.
// those articles already loaded to `<body>` var loadedArticles = [];
// ref: https://stackoverflow.com/questions/24768795/get-the-visible-height-of-a-div-with-jquery/26831113#26831113 functionelementVisibleHeight ($el) { var elH = $el.outerHeight(), H = $(window).height(), r = $el[0].getBoundingClientRect(), t=r.top, b=r.bottom; returnMath.max(0, t>0? Math.min(elH, H-t) : Math.min(b, H)); }
$(window).scroll(function () { ...
// I use lodash for array processing // assign the visible height value to each loaded articles _.each(loadedArticles, function (item) { item.visibleHeight = elementVisibleHeight($('#article-' + item.id)); });
// now get the article that has maximum visible area var maxItem = _.maxBy(loadedArticles, function (item) { return item.visibleHeight; });
// prevent it trigger multiple times if (maxItem.title != $('title').text()) { updateMeta(maxItem); } });
// ref: https://stackoverflow.com/questions/24768795/get-the-visible-height-of-a-div-with-jquery/26831113#26831113 functionelementVisibleHeight ($el) { var elH = $el.outerHeight(), H = $(window).height(), r = $el[0].getBoundingClientRect(), t=r.top, b=r.bottom; returnMath.max(0, t>0? Math.min(elH, H-t) : Math.min(b, H)); }
$(window).scroll(function () { // this is for before reach the bottom-most, it trigger to load next article let offsetPrefix = 500;
if ($(document).height() - $(this).height() - offsetPrefix < $(this).scrollTop()) { if (!loading) { loadAnotherArticle(); } }
// I use lodash for array processing // assign the visible height value to each loaded articles _.each(loadedArticles, function (item) { item.visibleHeight = elementVisibleHeight($('#article-' + item.id)); });
// now get the article that has maximum visible area var maxItem = _.maxBy(loadedArticles, function (item) { return item.visibleHeight; });
// prevent it trigger multiple times if (maxItem.title != $('title').text()) { updateMeta(maxItem); } });
P/S:
loadAnotherArticle() implement by yourself
The assumed article object is like
1 2 3 4 5 6 7 8 9 10
{ "id":1, "title":"How to kickstart JavaScript?", "description":"This is the description", "og_title":"How to kickstart JavaScript?", "og_description":"This is the open graph description", "image":"http://jslim.net/path/to/image.jpg", "url":"http://jslim.net/path/to/articles/", "content":"<div>The html content</div>", }