我正在尝试使用 JavaScript 创建一个分页系统。
基本情况:我有一个数据库,里面有相当长的文本(故事章节,5000字以上)。我想在网站上显示这些章节......但不是一次显示整个文本,因为这几乎会破坏可读性,而是在页面中。我没有问题显示文本,而是让页面正确。
我一直在环顾四周,发现了一个 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
});