JavaScript でページネーション システムを作成しようとしています。
基本的な状況: かなり長いテキスト (ストーリーの章、5000 語以上) を保持するデータベースがあります。これらの章を Web サイトに表示したいのですが、テキスト全体を一度に表示するのではなく、読みやすさをかなり損なうため、ページ単位で表示します。テキストの表示に問題はありませんが、ページを正しく表示することに問題はありません。
私は周りを見回していて、私がやりたいことをするJQueryコードに出くわしました...しかし、この方法には大きな注意点があります。テキストのページ付けが完了するまでに約 10 秒かかりますが、これは非常に長い待ち時間です。
コードの基本的な動作: テキストを単語に分割します (スペースで区切られます)。次に、単語を次々と innerHTML に追加しようとし、テキストが収まるはずのコンテナーよりも大きくなっているかどうかを確認します。
境界を破るたびに、前の文字列に戻り、新しいページを作成します。(テキストをスパンにカプセル化することにより、すぐに非表示/表示できます)これは機能しますが、これらのチェックを5000回以上実行する必要があるため、遅すぎます。
基本的に単語の量を取り、係数0.5で割り、バッファが必要なサイズよりも大きいかどうかを確認し、バッファが必要なサイズよりも「小さくなる」までこのプロセスを繰り返す近似システムを作成しようとしました初めて、その位置から、いっぱいになるまでバッファーをいっぱいにします。
ただし、正しく機能していないようです (ダブルワード、行、完全にいっぱいではなく、それでも遅すぎます)。
これは私が現在使用しているコードです。より簡単にするための修正と提案に感謝します。特に:より速く。ああ、いいえ、サーバー側でページングすることはオプションではありません。さまざまなブラウザー形式に適合するはずなので... 1280x768 解像度のフルスクリーンブラウザーでは、1024x768 解像度の小さなブラウザーよりもページ数が少なくなります。
function CreateChild(contentBox, Len, pageText, words) {
var Child = document.createElement("span");
Child.innerHTML = pageText;
contentBox.appendChild(Child);
if(Len == 0) ++Len;
words.splice(0, Len);
return words.length;
}
$(document).ready(function(){
var src = document.getElementById('Source');
var contentBox = document.getElementById('content');
var inner = document.getElementById('inner');
//get the text as an array of word-like things
var words = src.innerHTML.replace(/ +/g, " ").split(' '), wCount = words.length;
//start off with no page text
var pageText = null, cHeight = contentBox.offsetHeight;
while(words.length > 0) {
var Found = false;
pageText = words[0]; //Prevents constant checking for empty
wCount *= 0.5; //Searches, until the words fit in.
for(var i = 1; i < wCount; ++i) pageText += ' ' + words[i];
inner.innerHTML = pageText;
Distance = inner.offsetHeight - cHeight;
if(Distance < 40) { //Less than two lines
wCount = Math.floor(wCount);
if(Distance < 0) { //Already shorter than required. Fill.
for(var i = wCount; i < words.length; ++i) {
//add the next word to the pageText
var betterPageText = pageText + ' ' + words[i];
inner.innerHTML = betterPageText;
//Checks, whether the new words makes the buffer too big.
if(inner.offsetHeight > cHeight) {
wCount = CreateChild(contentBox, i, pageText, words);
Found = true;
break;
} else {
//this longer text still fits
pageText = betterPageText;
}
}
} else {
for(var i = wCount; i >= 0; --i) {
//Removes the last word from the text
var betterPageText = pageText.slice(0, pageText.length - words[i].length - 1);
inner.innerHTML = betterPageText;
//Is the text now short enough?
if(inner.offsetHeight <= cHeight) {
wCount = CreateChild(contentBox, i, pageText, words);
Found = true;
break;
} else {
pageText = betterPageText;
}
}
}
if(!Found) CreateChild(contentBox, i, pageText, words);
}
}
//Creates the final block with the remaining text.
Child = document.createElement("span");
Child.innerHTML = pageText;
contentBox.appendChild(Child);
//Removes the source and the temporary buffer, only the result remains.
contentBox.removeChild(inner);
src.parentNode.removeChild(src);
//The rest is the actual pagination code, but not the issue
});