2013-03-31 10 views
6

Cóż, nie jestem nawet pewien, czy można to zrobić przy moim obecnym podejściu. Próbuję dopasować zawartość dokumentu HTML do stron, które mają rozmiar bieżącej rzutni. Obecnie robię to przez iterowanie wszystkich elementów dokumentu i sprawdzanie, czy ich górne przesunięcie znajduje się w granicach bieżącej strony, kiedy nie jest, to przesunięcie staje się początkiem nowej strony, a granica strony jest ustawiona na to przesunięcie plus wysokość ekranu.Podziel HTML na strony, podziel długie akapity

Problem mam skierowane jest to, że często nie będzie elementem (paragraf, na przykład), którego wysokość jest większa niż samego widoku, więc nawet jeśli miejscach algorytm ten element na początku nowej strony, jego zawartość się przepełni. Próbuję znaleźć sposób na podzielenie takich elementów w taki sposób, aby pierwszy kawałek zajmował pozostałą część strony.

To powoduje dalsze trudności. Nawet gdybym mógł znaleźć sposób na określenie, ile tekstu akapitu wciąż mieści się w pozostałej części strony, a to samo w sobie okazało się dość trudne, nadal miałem problem z brakiem aktualizacji DOM natychmiast po podzieleniu akapit, który zepsułby obliczenia następnej strony lub przynajmniej zmusiłby mnie do zerwania rekursji, która jeszcze bardziej skomplikowałaby algorytm.

Wszelkie sugestie dotyczące podziału akapitu w taki sposób, że pierwszy plaster zajmuje pozostałe miejsce na stronie, są mile widziane. To jest mój kod do tej pory:

EDIT:Warto zauważyć, że to będzie działać tylko w bardzo prosty HTML, w którym nie istnieją absolutnie umieszczony lub elementów pływających. W moim przypadku nie stanowi to problemu.

var elementIndex = -1; 
var pages = 1; 
var pageBoundary = 0; 
var pageBreaks = []; 

function calculatePages() { 
    //first page boundary is window height 
    pageBoundary = $(window).height(); 
    //do calculations 
    iterateElements($("body")); 
    //print results 
    console.log(pageBreaks); 
} 

function iterateElements(parent) { 

    $.each($(parent).children(), function(i, e) { 
     //increase current element index 
     elementIndex = elementIndex + 1; 
     //get element's top offset 
     var offsetTop = $(e).offset().top; 
     //get the last position that the element occupies 
     var elementSpan = offsetTop + $(e).outerHeight(); 

     if ($(e).children().length == 0) { //only leaf nodes will be set as page breaks 
      //element's start position is outside page boundary 
      if (offsetTop >= pageBoundary) { 
       //mark page start with red in order to visualize 
       $(e).attr("style", "border-top: 1px solid red"); 

       //increase page count 
       pages = pages + 1; 
       //new page starts at element's top, next page boundary 
       //is element's starting position plus the viewport's height 
       pageBoundary = offsetTop + $(window).height(); 
       //store index of page break 
       pageBreaks.push(elementIndex); 
      } 
      //element's start position is inside current page, but contents overflow 
      else if (elementSpan >= pageBoundary) { 
       //NO IDEA WHAT TO DO HERE 
       //NEED A WAY TO SPLIT LARGE ELEMENTS 
      } 
     } 

     iterateElements(e); 
    }); 
} 

$(function() { 
    calculatePages(); 
}); 
+0

Jednym z naiwnych podejść byłoby obliczenie wielkości 1/2 wyrazów z akapitu i sprawdzenie, czy to pasuje, jeśli tak, podzielić duży akapit na dwa, a następnie podzielić ponownie. –

+0

Tak, to było moje początkowe podejście. Problem polega na tym, że może to pozostawić kilka fragmentów akapitu na następnej stronie, co zmieniłoby normalny przepływ tekstu. Ponadto, ponieważ DOM nie jest aktualizowany do czasu powrotu funkcji, wydaje się, że nie ma możliwości sprawdzenia, czy 1/2 słów pasuje do strony bez zerwania rekursji. – JayPea

+0

Jeśli pojedynczy akapit jest większy niż cała strona, oczywiście akapity zostaną podzielone. Jeśli chodzi o rekurencję, zwykle rekurencja jest w każdym przypadku niewłaściwą odpowiedzią na problem. –

Odpowiedz

2

Zrobiłem coś podobnego do tego. Podejście, które podjąłem, to sprawdzenie wysokości kontenera strony. Jeśli był większy niż maksimum, wiem, że elementy muszą zostać przeniesione na następną stronę.

Jeśli istnieje wiele elementów, mogę przenieść ostatni element do następnej strony.

Jeśli jest tylko 1 element, należy go podzielić. Nazwijmy ten element X. Aby utworzyć nowy akapit/sekcję na następnej stronie, nazwijmy ten element Y. Możesz teraz przenosić słowa lub znaki od końca elementu X na początek elementu Y aż do wysokości elementu X pasuje do strony.

Po tym można powtórzyć dla następnej strony.

+0

Cóż, myślę, że to jest tak blisko, jak to zrobię z takim podejściem. Postępowałem zgodnie z twoją radą kopiowania słów, dopóki element się nie dopasuje, ale ma to również pewne trudności. Chyba zacznę nowe pytanie z moim nowym problemem. – JayPea

+0

Właściwie to zadziałało całkiem dobrze, gdy tylko dobrze to zrobiłem, dzięki. – JayPea

+0

Możesz w ten sposób mieć strony z jednym słowem, prawda? – Mark

0

Możesz mieć plik indeksu i tworzyć ramki. Wiem, że to stara szkoła - ale może?

<html> 
    <head> 
    <title>Example for Stackoverflow</title> 
    </head> 
    <frameset rows="28,*,0" frameborder="0" border="0" framespacing="0"> 
     <frame name="topNav" src="top_nav.html" scrolling="no" noresize> 
    <frameset cols="110,*,150" frameborder="0" border="0" framespacing="0"> 
     <frame name="menu" src="menu_1.html" marginheight="0" marginwidth="0" scrolling="auto" noresize> 
     <frame name="content" src="content.html" marginheight="0" marginwidth="0" scrolling="auto" noresize> 
     <frame name="related" src="related.html" marginheight="0" marginwidth="0" scrolling="auto" noresize> 
    </frameset> 
    <noframes> 
    <p>This section (everything between the 'noframes' tags) will only be displayed if the users' browser doesn't support frames. You can provide a link to a non-frames version of the website here. Feel free to use HTML tags within this section.</p> 
    </noframes> 

    </frameset> 
    </html> 
+0

Dzięki, ale to nie jest to, czego szukam. Ostatecznie, po obliczeniu podziałów stron, użyłbym ich do wygenerowania kilku niezależnych dokumentów HTML. – JayPea