8

CSS

.page{ 
      width: 275px;
      hight: 380px;
      overflow: auto;
     }

HTML

<div class="page">dynamic text</div>

How to create a new div when the dynamic text is overflowing past the fixed height of the div?

Example:

<div class="page">Some dynamic texts will appear here</div>

When the dynamic text is overflowing past the fixed height of the div, the content above will be appear like this.

<div class="page">Some dynamic</div>
<div class="page">texts will</div>
<div class="page">appear here</div>

I've tried using wordwrap function in PHP wordwrap($dynamic_text, 600, '</div><div class="page">'); it's can running, but it had a problem when the character was copied from Ms.Words. So, by detecting the overflowing text, cut it, and then paste it into the new div element is the better solustion, i guess. But, I don't know how to do this solution using JQuery or Javascript.

Any ideas? Thanks in advance!

Dillon Burton
  • 131
  • 10
Jametson
  • 89
  • 1
  • 3
  • How are you adding the dynamic content? Just create a helper function to evaluate the height of the div in the success function of your dynamic request and perform the logic you need. We would need more information, anyway, such as under what circumstances does the text get split? 150 characters? on a letter? – Ohgodwhy Dec 25 '12 at 06:05
  • **+1** Great Question Alam Listyadi! Also, you have provided enough information. This question also applies to non-dynamic text, and it's understood by your example that the text-splitting occurs at point of overflow, while preserving whole word. P.S. I've undid my edit, as it also understood that you don't need trailing spaces. I do see a lot of jQuery in play in solving this question. Cheers! – arttronics Dec 25 '12 at 06:20
  • @Ohgodwhy I'm adding the dynamic content from database. This content support the html tags, the text get split when the content is oferflowing past the fixed height of the div. It's running like a Ms.Words, when the content is over the page height, it will be creat a new page no matter how many characters. Is it possible? – Jametson Dec 25 '12 at 06:24
  • 1
    check this out http://stackoverflow.com/questions/2112106/use-jquery-to-detect-container-overflow – rajesh kakawat Dec 25 '12 at 07:13

2 Answers2

2

You can do it, and it's way more than just a couple lines of code. It took a very experienced developer a couple days. Sorry, can't share the code.

Javascript: Put the whole content into the div. You may keep it hidden or out of the DOM for a while. Traverse the div's children. Find the one whose top+scrollHeight exceeds the div's height. Traverse it recursively. Eventually, you will either find an indivisible element, e.g., an image, that doesn't fit, or a position within a text node to split the text at. Remove that part and all further elements from the div. Add them to a new one.

There are a lot of details to address, so it's not simple. But doable.

full.stack.ex
  • 1,747
  • 2
  • 11
  • 13
1

I just had something similar working today while I was searching for an answer but there doesn't seem to be anything straight forward.

Although I am using Array.reduce() you should be able to do this with Array.forEach() or any other iterating code you like.

words.reduce(function(acc, value) 

This is done by calculating if the element will overflow if we add another word to it before we actually render it. The hacky thing here is to add another block element inside of it with visibility: hidden.

element.innerHTML = '<div style="visibility: hidden; height: 100%; width=100%">' + textToBeAdded + '</div>';

That way the block element still takes its parents dimensions and the parent element can be checked for overflow.

The way to check for overflow is to compare the element's scrolling height to its height:

if (element.scrollHeight > element.offsetHeight) 

If it overflows we leave it as is and create a new element and put the current value (word) in the iteration. Then we attach it to the same DOM tree as the previous element (as its parent's child... like having a new brother )

var newPageEl = document.createElement('div');
newPageEl.classList = 'page';
newPageEl.textContent = word;
parentElement.appendChild(newPageEl);

Hope this makes sense.

var page = document.getElementsByClassName('page')[0];

if (page.scrollHeight > page.offsetHeight) {
  // is overflowing
  fixOverflow(page);
}

function fixOverflow(element) {
  var words = element.textContent.split(' ');
  // delete previous text content
  element.textContent = '';

  words.reduce(function(acc, value) {
    // store current element's text
    var currentElementText = element.textContent.toString().trim();
    var textToBeAdded = currentElementText + ' ' + value;

    element.innerHTML = '<div style="visibility: hidden; height: 100%; width=100%">' + textToBeAdded + '</div>';
 
    if (element.scrollHeight > element.offsetHeight) {
      // is overflowing with the new word
      element.innerHTML = "";
      // leave the last page element as is
      element.textContent = currentElementText;
      // create another element with the new value to be added
      // ** IMPORTANT replace the memory of the previous element variable 
      element = createPageElement(value);
      // add it to the same DOM tree as the previous page element
      page.parentElement.appendChild(element); // could also be document.getElementById('page-container').appendChild(element);
    } else {
      // if not overflowing add another word 
      element.innerHTML = currentElementText + ' ' + value;    
    }
  }, "");
}

function createPageElement(text) {
  // create element with class page
  var newPageEl = document.createElement('div');
  newPageEl.classList = 'page';
  newPageEl.textContent = text;
  return newPageEl;
}
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Harry Theo
  • 784
  • 1
  • 8
  • 28