ATa*_*lor 2 javascript jquery pagination
我正在尝试使用 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
});
Run Code Online (Sandbox Code Playgroud)
我设法解决了我的问题,也多亏了 Rich 的建议。我在做什么:首先,我从“源”中获取文本(或者,我可以将整个文本直接写入 JS,效果相同)。
接下来,我将获取对任何临时缓冲区的目标的引用,临时缓冲区位于目标缓冲区内,因此它将保留宽度信息。
之后,我将整个文本拆分为单词(标准正则表达式,用一个空格替换多个空格后)。在此之后,我创建了一些变量,用于缓冲函数结果,因此不必重复调用函数。
现在的主要区别是:我采用 20 个单词的块,检查当前块是否超出边界(同样,将结果缓冲在变量中,因此它们不会被多次调用,函数调用等于有价值的微秒)。
一旦越过边界(或达到字符总数),循环就会停止,并且(假设边界导致“停止”),每次运行将文本缩短一个单词,直到文本再次适合。
最后,新文本被添加到一个新的跨度元素中,该元素被添加到内容框(但不可见,我稍后会解释原因),我刚刚“使用”的单词从单词数组中删除,并且wCount 变量会减少单词的数量。
冲洗并重复,直到呈现所有页面。您可以将 '20' 与任何其他值交换,该脚本可以使用任意数字,但是请记住,太低的数字会导致“添加段”中的大量运行,而太大的数字会导致在“回溯段”中有很多运行。
至于不可见:如果跨度保持可见,迟早会导致滚动条出现,从而有效地缩小浏览器窗口的宽度。反过来,这将允许较少的单词适合,并且所有后续页面将被扭曲(因为它们将与带有滚动条的窗口匹配,而“分页结果”将没有滚动条)。
下面是我使用的代码,我希望它会在将来对某人有所帮助。
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(' ');
//start off with no page text
var cHeight = contentBox.offsetHeight, wCount = words.length;
while(wCount > 0) {
var Len = 1, Overflow = false;
var pageText = words[0]; //Prevents the continued check on 'is pageText set'.
while(!Overflow && Len < wCount) { //Adds to the text, until the boundary is breached.
//20 words per run, but never more than the total amount of words.
for(var j = 0; j < 20 && Len < wCount; ++Len, ++j) pageText += ' ' + words[Len];
inner.innerHTML = pageText;
Overflow = (inner.offsetHeight > cHeight); //Determines, whether the boundary has been crossed.
}
if(Overflow) { //Will only be executed, if the boundary has been broken.
for(--Len; Len >= 0; --Len) { //Removes the last word of the text, until it fits again.
var pageText = pageText.slice(0, -(words[Len].length + 1)); //Shortens the text in question.
inner.innerHTML = pageText;
//Checks, whether the text still is too long.
if(inner.offsetHeight <= cHeight) break;//Breaks the loop
}
}
var Child = document.createElement("span");
Child.style.display = "none"; //Prevents the sidebars from showing (and distorting the following pages)
Child.innerHTML = pageText;
contentBox.appendChild(Child);
words.splice(0, Len);
wCount -= Len;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2227 次 |
| 最近记录: |