If the structure of the html page is complex, especially with precisely positioned elements or images, managing content can become quite challenging. However, if the content consists mainly of headings and paragraphs like in the epub.js example, it is possible to achieve.
The approach involves gradually adding content until just before the page overflows. By keeping track of where content starts and stops being added, moving to the next page simply requires adjusting the page start to the previous page's end (or vice versa when going back).
Steps for dividing content into pages
To begin, assuming all the content is in a single long string, split the content into an array of words and tags. This process is not straightforward as simply splitting by whitespace because whitespace between <
and >
should be disregarded, and tags should also be treated individually even without whitespace separating them from words.
You will need a function that can determine whether an element's content exceeds its boundaries. For reference, you can find a solution at this link.
Two variables, pageStart
and pageEnd
, are essential for keeping track of the array indexes that represent the beginning and end of the current page.
Starting from the index in pageStart
, add elements from the array as page content, checking for overflow after each addition. When overflow occurs, set the index you're currently at minus 1 as the endpoint for pageEnd
.
Maintaining continuity across page breaks
If everything goes smoothly, this method should fill the page effectively. To move to the next page, set your new pageStart
as pageEnd + 1
and repeat the process. Nonetheless, there are some potential issues that may need addressing.
One concern is what happens if a page overflows in the middle of a paragraph. While the closing tag, </p>
, is optional in HTML, the absence of an opening tag at the start of the next page is problematic. Therefore, it's crucial to check if the page's content begins with a tag. If it doesn't, locate the closest opening tag prior to the current pageStart
in the array and insert it before the rest of the content.
Additionally, in cases where a paragraph continues onto the next page, ensure that the last line on the current page remains justified. Check if pageEnd
falls within a paragraph, and if so, add syle="text-align-last:justify;"
to the opening tag of that paragraph.
Sample Implementation
An interactive demonstration showcasing these concepts can be viewed at https://codepen.io/anon/pen/ZMJMZZ.
In the provided example, all content is contained within a single element on an HTML page. The content retrieved from the container #page
is segmented into pages based on the size of #page
. Justifying the last line in case of a page break within a paragraph has not been implemented. Adjust the size of #page
in the CSS to observe how the content adapts; triggering a recalibration requires clicking forward and backward with the fixed page size. Binding the page size to the window dimensions allows for real-time recalculations by adding a resize event listener to the window that calls fillPage
.
Potential bugs may arise, leading to occasional display discrepancies such as skipping or repeating words at page borders. Nevertheless, this overview offers a starting point for implementing a similar content pagination system.