-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Making pages dynamically with Ajax
The first release of turn.js introduced a pretty simple way for adding new pages. In fact, the only thing you had to do was to add as many elements as pages you needed for your book or magazine. Quickly, this scheme brought up a problem in cases where the book contained a large amount of pages. The solution was to provide a way for creating pages on the fly. Therefore, the 3rd release of turn.js allows you to create pages dynamically.The API is also simple and consistent with the way you are familiar for setting event listeners. This new feature is the foundation in which any kind of e-reader app will be achievable.
In order to create pages dynamically, turn.js includes the ability to set an arbitrary number of pages during runtime.
It also comes with an internal garbage collection system that removes objects from memory that are not longer necessary for the reader. Therefore, turn.js is now keeping in DOM and references for only 6 pages. Let’s take an example:
If our reader is currently in the page 6, the view for that page will be 6,7
. From 6-7
, turn.js wants to keep in memory 4 more pages. Therefore, our DOM and JavaScript cache will have the pages [4, 5, 6, 7, 8, 9]
. For instance, if our reader is in page 1, the pages to keep in DOM are [1, 2, 3, 4, 5, 6]
.
In context, these pages in DOM are called range. That is, our range will be an array of two values where the first one is the first page and the second one the last page.
We are going to use the sample called ‘bible’, which comes with turn.js
Firstly, we create a book with 1000 pages.
$('#book').turn({pages: 1000});
We can also call the method pages
in order to set the amount of pages. Notice the difference between pages
and the other event called page
.
$('#book').turn(‘pages’, 1000);
Secondly, to create pages dynamically, we have to add a listener to the ‘turning’ event and there we want to read the range of pages that the reader will need. We also need a loop to inspect every page independently and for each page ask if that page is already in the reader, if not we need to add that page.
$('#book').bind('turning', function(e, page) {
var range = $(this).turn('range', page);
for (page = range[0]; page<=range[1]; page++)
addPage(page, $(this));
});
Then define the addPage
function:
function addPage(page, book) {
// Check if the page is not in the book
if (!book.turn('hasPage', page)) {
// Create an element for this page
var element = $('<div />').html('Loading…');
// Add the page
book.turn('addPage', element, page);
// Get the data for this page
$.ajax({url: "app?method=get-page-content&page="+page)
.done(function(data) {
element.html(data);
});
}
}
As you see, it is pretty simple and flexible for any implementation. For example, if you are loading data from the server with XHR, you can consider just one request per range.
In order to inspect the data in memory, you can explore $('#book').data()
#syllabus div:nth-child(odd) { background-image: -webkit-linear-gradient(left, #fff 95%, #ddd 100%); background-image: -moz-linear-gradient(left, #fff 95%, #ddd 100%); background-image: -o-linear-gradient(left, #fff 95%, #ddd 100%); background-image: -ms-linear-gradient(left, #fff 95%, #ddd 100%); box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); }
#syllabus div:nth-child(even) { background-image: -webkit-linear-gradient(right, #fff 95%, #ddd 100%); background-image: -moz-linear-gradient(right, #fff 95%, #ddd 100%); background-image: -o-linear-gradient(right, #fff 95%, #ddd 100%); background-image: -ms-linear-gradient(right, #fff 95%, #ddd 100%); box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); } #syllabus .cover { background: #333; }