Javascript - 如何计算动态数据集每页的分页范围数?

Javascript - How to calculate pagination range number for each page of dynamic dataset?

我正在构建一个自动分页计算器,可根据用户输入计算偏移量和范围。一个非常简单的任务,但由于 for 循环中从 0 开始的偏移量,我的算法已关闭。不管你怎么说,从 0 或 1 开始,数字总是不对的。我怎样才能使这项工作?

例如,输入 100 个项目,每页 25 个,差 4:

page : 1 | offset : 0 | range : 1 - 25 | total : 24
page : 2 | offset : 25 | range : 26 - 50 | total : 24
page : 3 | offset : 50 | range : 51 - 75 | total : 24
page : 4 | offset : 75 | range : 76 - 100 | total : 24

//event listener
var button = document.getElementById('submit');

//click
button.addEventListener('click',function(){
  
//div results  
var results = document.getElementById('results');
  
//clear div before appending
results.innerHTML= '';

//grab value
var total_items = document.getElementById('total_items').value;//331165139
var per_page =  document.getElementById('items_per_page').value;

//total pages
var total_pages = Math.ceil(total_items/per_page);

//iterate over pages
for(var x = 0; x<total_pages; x++){

//get page
var page = x+1;

//offset
var offset = (per_page * page) - per_page;

//range from
var from = ((page - 1) * per_page) + 1 ;

//range to
var to = per_page * page
var range = from + ' - ' + to;

//creating divs
var newDiv = document.createElement('div');
newDiv.innerHTML =  'page : ' + page + ' | offset : ' + offset + ' | range : ' + range + ' | total : ' + (to-from);
results.appendChild(newDiv);
 
}

})
<h3>Pagination Calculator</h3>
<hr>
<p>Calculates pagination automatically in the console</p>
<p>*Pop open the console</p>
<hr>
<label>total items </label>
<input id="total_items">
<label>limit per page</label>
<input id="items_per_page">
<button id="submit">Submit</button>
<hr>
<div id="results"></div>

关于您的代码有什么问题的最简单的答案是您有一个 off-by-one 错误。这些很常见。

当您要计算 ab 之间的整数时,不计算 b - a。是 b - a + 1。举个例子很容易看出。如果要统计58之间的数字,我们有5678,一共4 个数字。但是 8 - 53。我们需要添加一个来说明第二个包含的端点。

但我会以不同的方式看待这些问题。

在不尝试复制您的 UI 的情况下,我可能会编写如下函数:

const paginate = (items, per) =>
  Array .from ({length: Math .ceil (items / per)}, (_, i) => ({
    page: i + 1,
    offset: i * per,
    range: [i * per + 1, Math .min ((i + 1) * per, items)],
    total: Math .min ((i + 1) * per, items) - (i * per)
  }))

console .log (paginate (99, 8))
.as-console-wrapper {max-height: 100% !important; top: 0}

这一次获取所有页面。另一种方法是在请求时使用页码动态创建页面范围。 (也可以通过偏移来完成;各有利弊。)

可能看起来像这样:

const nextPage = (
  items = [], per = 10, page = 1, top = Math .min ((page + 1) * per, items)
) => ({
  page,
  range: [page * per + 1, top],
  total:  Math .max (0, top - (page * per)),
  done: top >= items
})
                  
console .log (nextPage (99, 8, 1))  // `done` is false
console .log (nextPage (99, 8, 2))  //  ...
console .log (nextPage (99, 8, 3))  //  ...
console .log ('....')               // `done` stays false
console .log (nextPage (99, 8, 11)) //  ...
console .log (nextPage (99, 8, 12)) // `done` is now true
.as-console-wrapper {max-height: 100% !important; top: 0}

此外,请注意所说的评论

My friend, do realize inputElement.value returns a string!!!

这碰巧没有伤害到你,因为你对输入值所做的唯一算术就是乘法或减法。如果您尝试添加,由于字符串连接,您可能会得到一些令人惊讶的答案。