Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how do I paginate text with jQuery / javascript?

Here's the brief...

I need to paginate very long amounts of text using jQuery or javascript. Now I have thought about doing character counts etc but the problem is that I'm not using monospace text so that's won't work.

Instead I'm using dynamically entered text (straight from my best friend wordpress).

Here's the setup:


my setup


I have placed the text in a div called bodytext which has overflow set to auto. Here's it's styling:

.bodytext {
width: 465px;
height: 454px;
display: block;
position: absolute;
display: block;
margin: 136px 25px;
font-family: 'Gentium Basic', serif;
color: #141414;
line-height: 1.5;
line-height: 1.5;
font-size: 17px;
overflow: hidden;
}

Anyway... the text overflows.

What I want to do is create a series of div's (with the bodytext class) all beside eachother that I can hook my buttons up to to toggle between.

I have found this good bit of information out though: every 18 lines I need to create a new div.

I have no idea how to work this out though.

I also need it to be able to handle large quantities of text... perhaps up to 1000 words at a time... resulting in say 10 pages...


any help would be lovely! Thanks for reading!

like image 280
Ben Potter Avatar asked Nov 12 '22 18:11

Ben Potter


1 Answers

This proof-of-concept will work (also with css3 columns), but be warned, there is a CPU cost; it's DOM-intensive and jQuery is required.

This requires the text to be divided into shorter paragraps (or any other tag), but it should be possible to even do that clientside if the text is in too big chunks.

Pseudo-markup:

ARTICLE
  header, intro etc
  SECTION
    paragraphs, divs, spans etc with (text) content

Code:

function paginate() {
  var screen_height = $(window).height();
  var max_page_height = screen_height * 0.8;

  var articles = $('article').toArray().map(function(node) {
    node = $(node);
    var sections = node.find('section');

    return {
      node: node,
      sections: sections,
      sectionChildren: sections.children(),
    };
  });

  function appendNewSection(article) {
    var section = $('<section class="columns page">')
    article.append(section);
    return section;
  }

  function re_paginate(article) {
    article.sections.detach(); // Important magic
    var section = appendNewSection(article.node);

    // Clone `sectionChildren` and append to DOM
    article.sectionChildren.clone().each(function(_, child) {
      child = $(child);

      if (section.height() > max_page_height) {
        section = appendNewSection(article.node);
      }

      if (child.is('ul') || child.is('ol')) {
        // Split list into shorter lists
        // NOTE! This approach can also be used to split long paragraphs...
        var list_children = child.children();
        list_children.detach(); // Important magic
        var blueprint = child.clone(); // Empty list blueprint
        var list = child;

        section.append(list);

        list_children.each(function(_, list_child) {
          if (section.height() > max_page_height) {
            // Append a new section with a new list and continue appending `list_children` therein
            section = appendNewSection(article.node);
            list = blueprint.clone();
            section.append(list);
          }
          list.append(list_child);
        });
      }
      else {
        section.append(child);
      }
    });
  }

  // Re-paginate articles
  confirm('Paginate articles to screen height?') && articles.filter(re_paginate);
}
like image 152
Gnimmelf Avatar answered Nov 15 '22 07:11

Gnimmelf