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();
});
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. –
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
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. –