1

Update: 27th December 2016

  1. I did change the heading, since every DOM element could be the target (it actually doesn't matter if it is a <p> element or not).

  2. I've provided some more informations about what I'm using and what I'm trying to achieve. Maybe there are native electron ways to achieve this? Or libs which could help me too?

Product: I'm going to extract tgz files with XMLs in it. Those XMLs will be used to automatically fill tables in the finished product. After that the tables and paragraphs will be editable where users can add new rows to the tables and also add new paragraphs to the page.

Framework: I'm using electron to fire the whole thing up.

Backend: NodeJS 7.x.x to make use of ES6 features

Libraries: jQuery, Bootstrap, Angular, Materialize, lodash, async, moment


Please keep in mind that I already did achieve all of my product needs. My original question was and still is if there is a more performant way of doing this:

I have a html page which can have 'n' containers called pages. A page can hold multiple <p> elements. This <p> elements are set to contenteditable="true".

Now I'm trying to create a javascript function which is checking the single page height with something like this:

// Set max container height to 10cm.
let containerMaxHeight = 377.95276 // 1 cm = 37.795276px;

if(containerElement.clientHeight > containerMaxHeight){
/**
 * do desired stuff.
 */
}

everything easy so far. The function is getting the innerHTML of the <p> element which is currently beeing edited and "break the site" into a new site if the page height is above the limit. I have thought out a recursion wich is removing words (most of the time 1-3) of the old <p> element and inserting them to a newly created page with a <p> element until the maximum height of the old page is set to its maximum value.

Here is an example of my recursion (simplified) which is removing words from the end of innerHTML like this:

let lastWordToBeRemoved = oldParagraphElement.split("\\s+").pop();

// append old value to new <p>
newParagraphElement.innerHTML += lastWordToBeRemoved;

// remove last Word from old <p>
oldParagraphElement.innerHTML.slice(0, -lastWordToBeRemoved.length);

/**
* Recheck height of old page container if it is above the 
* maximum redo above code
*/

I've startet out with this example: https://delight-im.github.io/HTML-Sheets-of-Paper/ as you can see the pages are getting bigger and bigger if you edit them. I've already prevented that with my JS function.

Now that you have an idea of what I'm doing: Is there a more performant and or elegant way of doing this? I'm highly interested to hear how you would solve this problem.

If there is anything still unclear let me know, I will update my answer.

Thank you in advance!

Regards, Megajin

Megajin
  • 2,648
  • 2
  • 25
  • 44
  • note that for you 10cm could be 377.95276px but that would differentiate per screen/resolution. – Kevin Kloet Dec 19 '16 at 15:48
  • I know, that's just to give ppl an idea why I'm using that weird value. However is there a way to tell JS I want 10cm without thinking about resolution? – Megajin Dec 19 '16 at 15:52
  • 1
    [this](http://stackoverflow.com/questions/10794891/getting-height-of-a-div-in-centimeter-using-jquery#answer-21059677) answer gives you the functionality to calculate it. – Kevin Kloet Dec 19 '16 at 15:54
  • Thank you very much, that helped me =). – Megajin Dec 19 '16 at 18:37
  • @Megajin still need a solution? – Rajshekar Reddy Dec 22 '16 at 09:03
  • @RajshekarReddy I would appreciate any idea. Like I wrote in the bounty message: I want to check if there are other ways to solve this. Like is there a more '2016/2017' way of doing this? Are there faster ways? – Megajin Dec 22 '16 at 09:05
  • 1
    I think it depends. If the maximum height is exceeded because the user wrote some letters, you probably only need to move a few words. But if the user pasted a big text, a binary search might be better than checking word by word. – Oriol Dec 26 '16 at 23:57
  • @Oriol that's a good point, thank you! – Megajin Dec 27 '16 at 08:31

1 Answers1

0

Instead of splitting words, I think you should insert another p element into the expected position instead. Then you can easily move the exceeding paragraph into the new page. For example

paragraphElement.innerHTML = paragraphElement.innerHTML.replace(lastWordToBeRemoved, '</p><p class="exceeding-paragraph">' + lastWordToBeRemoved);
newPage.insertBefore(oldPage.querySelector('.exceeding-paragraph'), newPage.firstElementChild);
Lewis
  • 14,132
  • 12
  • 66
  • 87
  • Thank you for your answer. While replacing is an option, how am I supposed to figure out the last word without splitting? – Megajin Dec 20 '16 at 08:49
  • 1
    @Megajin Your solution is fine. If you still need a faster one, then I would suggest you to use `String#slice` instead. For example `var lastWordToBeRemoved = paragraphContent.slice(paragraphContent.lastIndexOf(' ') + 1)` – Lewis Dec 20 '16 at 14:22
  • Thank you! That helped me +1 for your answer. I'm waiting to set a bounty, maybe I can attract a new way of doing this. At least I'm hoping so. If there will be no other answers (or just duplicates in some ways), I will accept yours. – Megajin Dec 20 '16 at 15:05