Skip to content

Instantly share code, notes, and snippets.

@e-orlov
Created September 28, 2015 11:43
Show Gist options
  • Save e-orlov/ce86239580934427af71 to your computer and use it in GitHub Desktop.
Save e-orlov/ce86239580934427af71 to your computer and use it in GitHub Desktop.
InfiniteScrollingByJohnMu
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Items</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="static/main.js" type="text/javascript"></script>
<link href="static/main.css" rel="stylesheet" type="text/css" />
<link rel="canonical" href="/items?page=3" />
<link rel="next" href="/items?page=4"/>
<link rel="prev" href="/items?page=2"/>
<script>initPaginator();</script>
<meta name="google-site-verification" content="OIKZIPdivZvzsmxLwlVDzTZ3OMxhnav0OjRxksHD12M" />
</head>
<body>
<div id="header">
<h1>Codex</h1>
<div>
This is a list of items from last.fm's GetHypedTracks<br>
</div>
</div>
<div id="scrollingcontent">
<div class="headertoo">&nbsp;</div>
<div class="headertoo">&nbsp;</div>
<div class="listitems" id="content">
<div class='listitempage' data-url='/items?page=3' data-pagination='[ <a href="/items?page=2">Previous</a> ] [ <a href="/items?page=4">Next</a> ] <a href="/items">1</a> <a href="/items?page=2">2</a> 3 <a href="/items?page=4">4</a> <a href="/items?page=5">5</a> <a href="/items?page=6">6</a> <a href="/items?page=7">7</a> <a href="/items?page=8">8</a> <a href="/items?page=9">9</a> <a href="/items?page=10">10</a> <a href="/items?page=11">11</a> <a href="/items?page=12">12</a> <a href="/items?page=13">13</a> <a href="/items?page=14">14</a> <a href="/items?page=15">15</a>'><div class="listpagination">Page 3</div>
<div class="listitem" data-page-url="/items?page=3">
<h2><a href="item?id=29">High Road</a></h2>
<p class="itemsub">Cults<br>
(#1 / ID 29)</p>
</div>
<div class="listitem" data-page-url="/items?page=3">
<h2><a href="item?id=30">Everybody Needs Love</a></h2>
<p class="itemsub">Drive-By Truckers<br>
(#2 / ID 30)</p>
</div>
<div class="listitem" data-page-url="/items?page=3">
<h2><a href="item?id=31">Another Tale From Another English Town</a></h2>
<p class="itemsub">Lanterns on the Lake<br>
(#3 / ID 31)</p>
</div>
<div class="listitem" data-page-url="/items?page=3">
<h2><a href="item?id=32">Strife</a></h2>
<p class="itemsub">Trivium<br>
(#4 / ID 32)</p>
</div>
<div class="listitem" data-page-url="/items?page=3">
<h2><a href="item?id=33">Avant Gardener</a></h2>
<p class="itemsub">Courtney Barnett<br>
(#5 / ID 33)</p>
</div>
<div class="listitem" data-page-url="/items?page=3">
<h2><a href="item?id=34">What About Your Friends</a></h2>
<p class="itemsub">TLC<br>
(#6 / ID 34)</p>
</div>
<div class="listitem" data-page-url="/items?page=3">
<h2><a href="item?id=35">There Can Be Only One</a></h2>
<p class="itemsub">Cass McCombs<br>
(#7 / ID 35)</p>
</div>
<div class="listitem" data-page-url="/items?page=3">
<h2><a href="item?id=36">History Eraser</a></h2>
<p class="itemsub">Courtney Barnett<br>
(#8 / ID 36)</p>
</div>
<div class="listitem" data-page-url="/items?page=3">
<h2><a href="item?id=37">Triumph of Disintegration</a></h2>
<p class="itemsub">of Montreal<br>
(#9 / ID 37)</p>
</div>
<div class="listitem" data-page-url="/items?page=3">
<h2><a href="item?id=38">The Addict</a></h2>
<p class="itemsub">Bo Saris<br>
(#10 / ID 38)</p>
</div>
</div>
</div>
</div>
<div id="pagination">
[ <a href="/items?page=2">Previous</a> ] [ <a href="/items?page=4">Next</a> ] <a href="/items">1</a> <a href="/items?page=2">2</a> 3 <a href="/items?page=4">4</a> <a href="/items?page=5">5</a> <a href="/items?page=6">6</a> <a href="/items?page=7">7</a> <a href="/items?page=8">8</a> <a href="/items?page=9">9</a> <a href="/items?page=10">10</a> <a href="/items?page=11">11</a> <a href="/items?page=12">12</a> <a href="/items?page=13">13</a> <a href="/items?page=14">14</a> <a href="/items?page=15">15</a>
</div>
<script type="text/javascript">
next_data_url = '/items?page=4&type=json';
prev_data_url = '/items?page=2&type=json';
primeCache();
</script>
<div class="footer">&nbsp;</div>
</body>
// js file
var next_data_url; // replaced when loading more
var prev_data_url; // replaced when loading more
var next_data_cache;
var prev_data_cache;
var last_scroll = 0;
var is_loading = 0; // simple lock to prevent loading when loading
var hide_on_load = false; // ID that can be hidden when content has been loaded
function loadFollowing() {
if (next_data_url=="") {
$('div.pagination').show();
} else {
is_loading = 1; // note: this will break when the server doesn't respond
$('div.pagination').hide();
function showFollowing(data) {
$('div.listitempage:last').after(data.response);
next_data_url = data.next_data_url;
next_data_cache = false;
$.getJSON(next_data_url, function(preview_data) {
next_data_cache = preview_data;
});
}
if (next_data_cache) {
showFollowing(next_data_cache);
is_loading = 0;
} else {
$.getJSON(next_data_url, function(data) {
showFollowing(data);
is_loading = 0;
});
}
}
};
function loadPrevious() {
if (prev_data_url=="") {
$('div.pagination').show();
} else {
is_loading = 1; // note: this will break when the server doesn't respond
$('div.pagination').hide();
function showPrevious(data) {
$('div.listitempage:first').before(data.response);
item_height = $("div.listitempage:first").height();
window.scrollTo(0, $(window).scrollTop()+item_height); // adjust scroll
prev_data_url = data.prev_data_url;
prev_data_cache = false;
$.getJSON(prev_data_url, function(preview_data) {
prev_data_cache = preview_data;
});
if (hide_on_load) {
$(hide_on_load).hide();
hide_on_load = false;
}
}
if (prev_data_cache) {
showPrevious(prev_data_cache);
is_loading = 0;
} else {
$.getJSON(prev_data_url, function(data) {
showPrevious(data);
is_loading = 0;
});
}
}
};
function mostlyVisible(element) {
// if ca 25% of element is visible
var scroll_pos = $(window).scrollTop();
var window_height = $(window).height();
var el_top = $(element).offset().top;
var el_height = $(element).height();
var el_bottom = el_top + el_height;
return ((el_bottom - el_height*0.25 > scroll_pos) &&
(el_top < (scroll_pos+0.5*window_height)));
}
function initPaginator() {
$(window).scroll(function() {
// handle scroll events to update content
var scroll_pos = $(window).scrollTop();
if (scroll_pos >= 0.9*($(document).height() - $(window).height())) {
if (is_loading==0) loadFollowing();
}
if (scroll_pos <= 0.9*$("#header").height()) {
if (is_loading==0) loadPrevious();
}
// Adjust the URL based on the top item shown
// for reasonable amounts of items
if (Math.abs(scroll_pos - last_scroll)>$(window).height()*0.1) {
last_scroll = scroll_pos;
$(".listitempage").each(function(index) {
if (mostlyVisible(this)) {
history.replaceState(null, null, $(this).attr("data-url"));
$("#pagination").html($(this).attr("data-pagination"));
return(false);
}
});
}
});
$(document).ready(function () {
// if we have enough room, load the next batch
if ($(window).height()>$("#scrollingcontent").height()) {
if (next_data_url!="") {
loadFollowing();
} else {
var filler = document.createElement("div");
filler.id = "filler";
filler.style.height = ($(window).height() -
$("#scrollingcontent").height())+ "px";
$("#scrollingcontent").after(filler);
hide_on_load = "filler";
}
}
// scroll down to hide empty room
head_height = $("#header").height();
window.scrollTo(0, head_height);
});
}
function primeCache() {
$.getJSON(prev_data_url, function(data) { prev_data_cache=data; } );
$.getJSON(next_data_url, function(data) { next_data_cache=data; } );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment