【问题标题】:Simple pagination in javascriptjavascript中的简单分页
【发布时间】:2014-10-15 14:05:54
【问题描述】:

我正在尝试为我的网站进行分页。 (http://anuntorhei.md)

代码

var someVar = 50;


function someStupidFunction() {
        if (objJson.length > 50) {
                document.getElementById("nextPage").style.visibility = "visible";
        }

        if (someVar <= 50) {
                document.getElementById("prevPage").style.visibility ="hidden";
        } else {
                document.getElementById("prevPage").style.visibility = "visible";
        }
}


function nextPage() {
        document.getElementById("listingTable").innerHTML = "";

        if (someVar < objJson.length) {
                document.getElementById("nextPage").style.visibility = "visible";
        } else {
                document.getElementById("nextPage").style.visibility = "hidden";
        }

        for (var i = someVar - 50; i < someVar; i++) {
                document.getElementById("listingTable").innerHTML += objJson[i].adName + "<br>";
        }

        someVar += 50;

        document.getElementById("prevPage").style.visibility = "visible";
}


function prevPage() {
        document.getElementById("listingTable").innerHTML = "";

        if (someVar > 50) {
                document.getElementById("prevPage").style.visibility = "visible";
        } else {
                document.getElementById("prevPage").style.visibility = "hidden";
        }

        for (var i = someVar - 50; i < someVar; i++) {
                document.getElementById("listingTable").innerHTML += objJson[i].adName + "<br>";
        }

        someVar -= 50;

        document.getElementById("nextPage").style.visibility = "visible";
}

但是当someVar 大于objJson.length 时,我无法理解如何“隐藏”nextPage 按钮。

当我到达“结束”时,nextPage 按钮在比objJson 小于someVar 后消失。这段代码有什么问题?

如何更改它以使其完美?对不起我的英语不好,无法解释我需要什么,希望你能理解我的需要!

【问题讨论】:

  • 在那个链接中我没有看到任何分页。无论如何,如果你使用三元运算符,你可以清理你的代码:jsfiddle.net/rwntwwob
  • 因为我首先测试了分页(或其他东西),当我喜欢这些东西的工作方式时,我把它放在主站点上!

标签: javascript pagination


【解决方案1】:

我会解决您的任何问题...但这里有一个改进的模式,您应该遵循以减少代码重复。

不过,作为旁注,您应该考虑在客户端进行分页。因为如果您有一个庞大的数据集,这意味着您需要在页面加载之前下载所有数据。最好改为实现服务器端分页。

小提琴:http://jsfiddle.net/Lzp0dw83/

HTML

<div id="listingTable"></div>
<a href="javascript:prevPage()" id="btn_prev">Prev</a>
<a href="javascript:nextPage()" id="btn_next">Next</a>
page: <span id="page"></span>

Javascript(放在任何地方):

var current_page = 1;
var records_per_page = 2;

var objJson = [
    { adName: "AdName 1"},
    { adName: "AdName 2"},
    { adName: "AdName 3"},
    { adName: "AdName 4"},
    { adName: "AdName 5"},
    { adName: "AdName 6"},
    { adName: "AdName 7"},
    { adName: "AdName 8"},
    { adName: "AdName 9"},
    { adName: "AdName 10"}
]; // Can be obtained from another source, such as your objJson variable

function prevPage()
{
    if (current_page > 1) {
        current_page--;
        changePage(current_page);
    }
}

function nextPage()
{
    if (current_page < numPages()) {
        current_page++;
        changePage(current_page);
    }
}

function changePage(page)
{
    var btn_next = document.getElementById("btn_next");
    var btn_prev = document.getElementById("btn_prev");
    var listing_table = document.getElementById("listingTable");
    var page_span = document.getElementById("page");

    // Validate page
    if (page < 1) page = 1;
    if (page > numPages()) page = numPages();

    listing_table.innerHTML = "";

    for (var i = (page-1) * records_per_page; i < (page * records_per_page); i++) {
        listing_table.innerHTML += objJson[i].adName + "<br>";
    }
    page_span.innerHTML = page;

    if (page == 1) {
        btn_prev.style.visibility = "hidden";
    } else {
        btn_prev.style.visibility = "visible";
    }

    if (page == numPages()) {
        btn_next.style.visibility = "hidden";
    } else {
        btn_next.style.visibility = "visible";
    }
}

function numPages()
{
    return Math.ceil(objJson.length / records_per_page);
}

window.onload = function() {
    changePage(1);
};

2014 年 8 月 27 日更新

上面有一个错误,当特定页面(通常是最后一页)不包含 records_per_page 记录数时,for 循环会出错,因为它试图访问不存在的索引。

修复很简单,通过在 for 循环中添加一个额外的检查条件来说明 objJson 的大小:

更新小提琴:http://jsfiddle.net/Lzp0dw83/1/

for (var i = (page-1) * records_per_page; i < (page * records_per_page) && i < objJson.length; i++)

【讨论】:

  • 感谢您的帮助! prevPage 函数工作得很好,但是 nextPage 发生了一些事情。例如,如果objJson.length是547,我有19页,但是当我在18页按下next按钮时,页面再次等于18并且next按钮不会消失!我认为“i”变量的算法错误,或者可能是“错误”在另一个地方。您对此有何看法?
【解决方案2】:

我为一般的集合创建了一个可以满足此要求的类结构。它看起来像这样:

class Collection {

    constructor() {
        this.collection = [];
        this.index = 0;
    }

    log() {
        return console.log(this.collection);
    }

    push(value) {
        return this.collection.push(value);
    }

    pushAll(...values) {
        return this.collection.push(...values);
    }

    pop() {
        return this.collection.pop();
    }

    shift() {
        return this.collection.shift();
    }

    unshift(value) {
        return this.collection.unshift(value);
    }

    unshiftAll(...values) {
        return this.collection.unshift(...values);
    }

    remove(index) {
        return this.collection.splice(index, 1);
    }

    add(index, value) {
        return this.collection.splice(index, 0, value);
    }

    replace(index, value) {
        return this.collection.splice(index, 1, value);
    }

    clear() {
        this.collection.length = 0;
    }

    isEmpty() {
        return this.collection.length === 0;
    }

    viewFirst() {
        return this.collection[0];
    }

    viewLast() {
        return this.collection[this.collection.length - 1];
    }

    current(){
        if((this.index <= this.collection.length - 1) && (this.index >= 0)){
            return this.collection[this.index];
        }
        else{
            return `Object index exceeds collection range.`;
        }
    }

    next() {
        this.index++;
        this.index > this.collection.length - 1 ? this.index = 0 : this.index;
        return this.collection[this.index];
    }

    previous(){
        this.index--;
        this.index < 0 ? (this.index = this.collection.length-1) : this.index;
        return this.collection[this.index];
    }
}

...本质上,您要做的是将页面的任何长度的数组推入类对象,然后使用 next() 和 previous() 函数显示任何“页面”(索引) 你想显示。基本上看起来像这样:

let books = new Collection();
let firstPage - [['dummyData'], ['dummyData'], ['dummyData'], ['dummyData'], ['dummyData'],];
let secondPage - [['dumberData'], ['dumberData'], ['dumberData'], ['dumberData'], ['dumberData'],];
books.pushAll(firstPage, secondPage); // loads each array individually
books.current() // display firstPage
books.next() // display secondPage

【讨论】:

    【解决方案3】:

    下面是作为函数的分页逻辑

    
    function Pagination(pageEleArr, numOfEleToDisplayPerPage) {
        this.pageEleArr = pageEleArr;
        this.numOfEleToDisplayPerPage = numOfEleToDisplayPerPage;
        this.elementCount = this.pageEleArr.length;
        this.numOfPages = Math.ceil(this.elementCount / this.numOfEleToDisplayPerPage);
        const pageElementsArr = function (arr, eleDispCount) {
            const arrLen = arr.length;
            const noOfPages = Math.ceil(arrLen / eleDispCount);
            let pageArr = [];
            let perPageArr = [];
            let index = 0;
            let condition = 0;
            let remainingEleInArr = 0;
    
            for (let i = 0; i < noOfPages; i++) {
    
                if (i === 0) {
                    index = 0;
                    condition = eleDispCount;
                }
                for (let j = index; j < condition; j++) {
                    perPageArr.push(arr[j]);
                }
                pageArr.push(perPageArr);
                if (i === 0) {
                    remainingEleInArr = arrLen - perPageArr.length;
                } else {
                    remainingEleInArr = remainingEleInArr - perPageArr.length;
                }
    
                if (remainingEleInArr > 0) {
                    if (remainingEleInArr > eleDispCount) {
                        index = index + eleDispCount;
                        condition = condition + eleDispCount;
                    } else {
                        index = index + perPageArr.length;
                        condition = condition + remainingEleInArr;
                    }
                }
                perPageArr = [];
            }
            return pageArr;
        }
        this.display = function (pageNo) {
            if (pageNo > this.numOfPages || pageNo <= 0) {
                return -1;
            } else {
                console.log('Inside else loop in display method');
                console.log(pageElementsArr(this.pageEleArr, this.numOfEleToDisplayPerPage));
                console.log(pageElementsArr(this.pageEleArr, this.numOfEleToDisplayPerPage)[pageNo - 1]);
                return pageElementsArr(this.pageEleArr, this.numOfEleToDisplayPerPage)[pageNo - 1];
            }
        }
    }
    
    const p1 = new Pagination(['a', 'b', 'c', 'd', 'e', 'f', 'g'], 3);
    console.log(p1.elementCount);
    console.log(p1.pageEleArr);
    console.log(p1.numOfPages);
    console.log(p1.numOfEleToDisplayPerPage);
    console.log(p1.display(3));
    

    【讨论】:

    • 这个的html在哪里?
    • 非常好的功能。我会推荐使用它。
    • 分页点(多次)是不想将 40,000 个项目加载到数组中;但仅检索/加载要显示的项目。所以最好将项目的计数传递给分页函数。
    【解决方案4】:

    一个简单的客户端分页示例,其中数据在页面加载时仅获取一次。

    // dummy data
            const myarr = [{ "req_no": 1, "title": "test1" },
            { "req_no": 2, "title": "test2" },
            { "req_no": 3, "title": "test3" },
            { "req_no": 4, "title": "test4" },
            { "req_no": 5, "title": "test5" },
            { "req_no": 6, "title": "test6" },
            { "req_no": 7, "title": "test7" },
            { "req_no": 8, "title": "test8" },
            { "req_no": 9, "title": "test9" },
            { "req_no": 10, "title": "test10" },
            { "req_no": 11, "title": "test11" },
            { "req_no": 12, "title": "test12" },
            { "req_no": 13, "title": "test13" },
            { "req_no": 14, "title": "test14" },
            { "req_no": 15, "title": "test15" },
            { "req_no": 16, "title": "test16" },
            { "req_no": 17, "title": "test17" },
            { "req_no": 18, "title": "test18" },
            { "req_no": 19, "title": "test19" },
            { "req_no": 20, "title": "test20" },
            { "req_no": 21, "title": "test21" },
            { "req_no": 22, "title": "test22" },
            { "req_no": 23, "title": "test23" },
            { "req_no": 24, "title": "test24" },
            { "req_no": 25, "title": "test25" },
            { "req_no": 26, "title": "test26" }];
    
            // on page load collect data to load pagination as well as table
            const data = { "req_per_page": document.getElementById("req_per_page").value, "page_no": 1 };
    
            // At a time maximum allowed pages to be shown in pagination div
            const pagination_visible_pages = 4;
    
    
            // hide pages from pagination from beginning if more than pagination_visible_pages
            function hide_from_beginning(element) {
                if (element.style.display === "" || element.style.display === "block") {
                    element.style.display = "none";
                } else {
                    hide_from_beginning(element.nextSibling);
                }
            }
            
            // hide pages from pagination ending if more than pagination_visible_pages
            function hide_from_end(element) {
                if (element.style.display === "" || element.style.display === "block") {
                    element.style.display = "none";
                } else {
                    hide_from_beginning(element.previousSibling);
                }
            }
            
            // load data and style for active page
            function active_page(element, rows, req_per_page) {
                var current_page = document.getElementsByClassName('active');
                var next_link = document.getElementById('next_link');
                var prev_link = document.getElementById('prev_link');
                var next_tab = current_page[0].nextSibling; 
                var prev_tab = current_page[0].previousSibling;
                current_page[0].className = current_page[0].className.replace("active", "");
                if (element === "next") {
                    if (parseInt(next_tab.text).toString() === 'NaN') {
                        next_tab.previousSibling.className += " active";
                        next_tab.setAttribute("onclick", "return false");
                    } else {
                        next_tab.className += " active"
                        render_table_rows(rows, parseInt(req_per_page), parseInt(next_tab.text));
                        if (prev_link.getAttribute("onclick") === "return false") {
                            prev_link.setAttribute("onclick", `active_page('prev',\"${rows}\",${req_per_page})`);
                        }
                        if (next_tab.style.display === "none") {
                            next_tab.style.display = "block";
                            hide_from_beginning(prev_link.nextSibling)
                        }
                    }
                } else if (element === "prev") {
                    if (parseInt(prev_tab.text).toString() === 'NaN') {
                        prev_tab.nextSibling.className += " active";
                        prev_tab.setAttribute("onclick", "return false");
                    } else {
                        prev_tab.className += " active";
                        render_table_rows(rows, parseInt(req_per_page), parseInt(prev_tab.text));
                        if (next_link.getAttribute("onclick") === "return false") {
                            next_link.setAttribute("onclick", `active_page('next',\"${rows}\",${req_per_page})`);
                        }
                        if (prev_tab.style.display === "none") {
                            prev_tab.style.display = "block";
                            hide_from_end(next_link.previousSibling)
                        }
                    }
                } else {
                    element.className += "active";
                    render_table_rows(rows, parseInt(req_per_page), parseInt(element.text));
                    if (prev_link.getAttribute("onclick") === "return false") {
                        prev_link.setAttribute("onclick", `active_page('prev',\"${rows}\",${req_per_page})`);
                    }
                    if (next_link.getAttribute("onclick") === "return false") {
                        next_link.setAttribute("onclick", `active_page('next',\"${rows}\",${req_per_page})`);
                    }
                }
            }
    
            // Render the table's row in table request-table
            function render_table_rows(rows, req_per_page, page_no) {
                const response = JSON.parse(window.atob(rows));
                const resp = response.slice(req_per_page * (page_no - 1), req_per_page * page_no)
                $('#request-table').empty()
                $('#request-table').append('<tr><th>Index</th><th>Request No</th><th>Title</th></tr>');
                resp.forEach(function (element, index) {
                    if (Object.keys(element).length > 0) {
                        const { req_no, title } = element;
                        const td = `<tr><td>${++index}</td><td>${req_no}</td><td>${title}</td></tr>`;
                        $('#request-table').append(td)
                    }
                });
            }
    
            // Pagination logic implementation
            function pagination(data, myarr) {
                const all_data = window.btoa(JSON.stringify(myarr));
                $(".pagination").empty();
                if (data.req_per_page !== 'ALL') {
                    let pager = `<a href="#" id="prev_link" onclick=active_page('prev',\"${all_data}\",${data.req_per_page})>&laquo;</a>` +
                        `<a href="#" class="active" onclick=active_page(this,\"${all_data}\",${data.req_per_page})>1</a>`;
                    const total_page = Math.ceil(parseInt(myarr.length) / parseInt(data.req_per_page));
                    if (total_page < pagination_visible_pages) {
                        render_table_rows(all_data, data.req_per_page, data.page_no);
                        for (let num = 2; num <= total_page; num++) {
                            pager += `<a href="#" onclick=active_page(this,\"${all_data}\",${data.req_per_page})>${num}</a>`;
                        }
                    } else {
                        render_table_rows(all_data, data.req_per_page, data.page_no);
                        for (let num = 2; num <= pagination_visible_pages; num++) {
                            pager += `<a href="#" onclick=active_page(this,\"${all_data}\",${data.req_per_page})>${num}</a>`;
                        }
                        for (let num = pagination_visible_pages + 1; num <= total_page; num++) {
                            pager += `<a href="#" style="display:none;" onclick=active_page(this,\"${all_data}\",${data.req_per_page})>${num}</a>`;
                        }
                    }
                    pager += `<a href="#" id="next_link" onclick=active_page('next',\"${all_data}\",${data.req_per_page})>&raquo;</a>`;
                    $(".pagination").append(pager);
                } else {
                    render_table_rows(all_data, myarr.length, 1);
                }
            }
    
            //calling pagination function
            pagination(data, myarr);
    
    
            // trigger when requests per page dropdown changes
            function filter_requests() {
                const data = { "req_per_page": document.getElementById("req_per_page").value, "page_no": 1 };
                pagination(data, myarr);
            }
    .box {
    	float: left;
    	padding: 50px 0px;
    }
    
    .clearfix::after {
    	clear: both;
    	display: table;
    }
    
    .options {
    	margin: 5px 0px 0px 0px;
    	float: left;
    }
    
    .pagination {
    	float: right;
    }
    
    .pagination a {
    	color: black;
    	float: left;
    	padding: 8px 16px;
    	text-decoration: none;
    	transition: background-color .3s;
    	border: 1px solid #ddd;
    	margin: 0 4px;
    }
    
    .pagination a.active {
    	background-color: #4CAF50;
    	color: white;
    	border: 1px solid #4CAF50;
    }
    
    .pagination a:hover:not(.active) {
    	background-color: #ddd;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div>
        <table id="request-table">
       </table>
    </div>
    
    <div class="clearfix">
    	<div class="box options">
    		<label>Requests Per Page: </label>
          <select id="req_per_page" onchange="filter_requests()">
    			<option>5</option>
    			<option>10</option>
    			<option>ALL</option>
    		</select>
    	</div>
    	<div class="box pagination">
    	</div>
    </div>

    【讨论】:

      【解决方案5】:

      因此您可以使用库进行分页逻辑https://github.com/pagino/pagino-js

      【讨论】:

        【解决方案6】:

        这是迄今为止对我来说最好的一个,它将在特定偏移处包含“...”

        function pages(current_page, last_page, onSides = 3) {
                // pages
                let pages = [];
                // Loop through
                for (let i = 1; i <= last_page; i++) {
                    // Define offset
                    let offset = (i == 1 || last_page) ? onSides + 1 : onSides;
                    // If added
                    if (i == 1 || (current_page - offset <= i && current_page + offset >= i) || 
                        i == current_page || i == last_page) {
                        pages.push(i);
                    } else if (i == current_page - (offset + 1) || i == current_page + (offset + 1)) {
                        pages.push('...');
                    }
                }
                return pages;
            }
        

        【讨论】:

          【解决方案7】:

          我假设您将在每个页面中显示 10 个数据

          HTML:-

          <!DOCTYPE html>
          <html>
          <head>
              <title>pagination</title>
              <link rel="stylesheet"  href="pathofcssfile.css">
          </head>
          <body>
              <div>
                  <table id="user"></table>
              </div>
              <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
              <ul>
              <li value="1">1</li>
              <li value="2">2</li>
              <li value="3">3</li>
              <li value="4">4</li>
              <li value="5">5</li>
              <li value="6">6</li>
              <li value="7">7</li>
              <li value="8">8</li>
              <li value="9">9</li>
              <li value="10">10</li>
          
              </ul>
          
              <script src="pathnameofjsfile.js" type="text/javascript"></script>
          </body>
          </html>
          

          JS:-

          var xhr = new XMLHttpRequest();
          xhr.open('GET',"https://jsonplaceholder.typicode.com/albums",true);
          xhr.send();
          
          var udata;
          
          xhr.onload = function() 
          {
              if(this.status == 200) 
              {
                  var userdata = JSON.parse(this.responseText);
                  console.log(userdata);
                  udata = userdata;
                  data(1);
              }
          }
          
          $("li").click(function ()
          {       
          var a = $(this).attr("value");
          console.log("value li "+ a);
          data(a);
          });
          
          function data(a)
          {  
              var output = "";
              for(i=((a-1)*10);i<(a*10);i++)
              {
                  output +='<tr>'+
                           '<td>'+ udata[i].userId + '</td>'+
                           '<td>'+ udata[i].id + '</td>'+
                           '<td>'+ udata[i].title + '</td>'+ '<br>'
                           '</tr>';
              }
              document.getElementById('user').innerHTML = output;
          }
          

          CSS:-

          ul{
          display: flex;
          list-style-type:none;
          padding: 20px;
          }
          
          li{
          padding: 20px;
          }
          
          td,tr{
              padding: 10px;
          }
          

          【讨论】:

            【解决方案8】:

            以下是接受用户计数并在 Javascript 中执行分页的逻辑。 它打印字母。希望能帮助到你!!。谢谢。

            /*
            *****
            USER INPUT : NUMBER OF SUGGESTIONS.
            *****
            */
            
            var recordSize = prompt('please, enter the Record Size');
            console.log(recordSize);
            
            
            /*
            *****
            POPULATE SUGGESTIONS IN THE suggestion_set LIST.
            *****
            */
            var suggestion_set = [];
            counter = 0;
            
            asscicount = 65;
            do{
            if(asscicount <= 90){
            	var temp = String.fromCharCode(asscicount);
            	suggestion_set.push(temp);
            	asscicount += 1;    	
            }else{
            	asscicount = 65;
            	var temp = String.fromCharCode(asscicount);
            	suggestion_set.push(temp);	
            	asscicount += 1;    	
            }
            counter += 1;
            }while(counter < recordSize);
            
            console.log(suggestion_set);	
            
            
            
            /*
            *****
            LOGIC FOR PAGINATION
            *****
            */
            
            var totalRecords = recordSize, pageSize = 6;
            var q = Math.floor(totalRecords/pageSize);
            var r = totalRecords%pageSize;
            var itr = 1;
            
            if(r==0 ||r==1 ||r==2) {
            itr=q;
            }
            else {
            itr=q+1;
            }
            console.log(itr);
            
            var output = "", pageCnt=1, newPage=false;
            
            if(totalRecords <= pageSize+2) {
            output += "\n";
            
            	for(var i=0; i < totalRecords; i++){
            		output += suggestion_set[i] + "\t";
            	}
            }
            
            else {
            	output += "\n";
            	for(var i=0; i<totalRecords; i++) {
            		//output += (i+1) + "\t";
            		if(pageCnt==1){
            		output += suggestion_set[i] + "\t";
            		if((i+1)==(pageSize+1)) {
            		output += "Next" + "\t";
            		pageCnt++;
            		newPage=true;
            	}
            }
            else {
            if(newPage) {
            output += "\n" + "Previous" + "\t";
            newPage = false;
            }
            output += suggestion_set[i] + "\t";
            if((i+1)==(pageSize*pageCnt+1) && (pageSize*pageCnt+1)<totalRecords) {
            if((i+2) == (pageSize*pageCnt+2) && pageCnt==itr) {
            output += (suggestion_set[i] + 1) + "\t";
            break;
            }
            else {
            output += "Next" + "\t";
            pageCnt++;
            newPage=true;
            }
            }
            }
            }
            }
            console.log(output);

            【讨论】:

              【解决方案9】:

              文件:icons.svg

              <svg aria-hidden="true" style="position: absolute; width: 0; height: 0; overflow: hidden;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
              <defs>
              <symbol id="icon-triangle-left" viewBox="0 0 20 20">
              <title>triangle-left</title>
              <path d="M14 5v10l-9-5 9-5z"></path>
              </symbol>
              <symbol id="icon-triangle-right" viewBox="0 0 20 20">
              <title>triangle-right</title>
              <path d="M15 10l-9 5v-10l9 5z"></path>
              </symbol>
              </defs>
              </svg>
              

              文件:style.css

               .results__btn--prev{
                  float: left;
                  flex-direction: row-reverse; }
                .results__btn--next{
                  float: right; }
              

              文件index.html:

              <body>
              <form class="search">
                              <input type="text" class="search__field" placeholder="Search over 1,000,000 recipes...">
                              <button class="btn search__btn">
                                  <svg class="search__icon">
                                      <use href="img/icons.svg#icon-magnifying-glass"></use>
                                  </svg>
                                  <span>Search</span>
                              </button>
                          </form>
                   <div class="results">
                       <ul class="results__list">
                       </ul>
                       <div class="results__pages">
                       </div>
                   </div>
              </body>
              

              文件:searchView.js

              export const element = {
                  searchForm:document.querySelector('.search'),
                  searchInput: document.querySelector('.search__field'),
                  searchResultList: document.querySelector('.results__list'),
                  searchRes:document.querySelector('.results'),
                  searchResPages:document.querySelector('.results__pages')
              
              }
              export const getInput = () => element.searchInput.value;
              export const clearResults = () =>{
                  element.searchResultList.innerHTML=``;
                  element.searchResPages.innerHTML=``;
              }
              export const clearInput = ()=> element.searchInput.value = "";
              
              const limitRecipeTitle = (title, limit=17)=>{
                  const newTitle = [];
                  if(title.length>limit){
                      title.split(' ').reduce((acc, cur)=>{
                          if(acc+cur.length <= limit){
                              newTitle.push(cur);
                          }
                          return acc+cur.length;
                      },0);
                  }
              
                  return `${newTitle.join(' ')} ...`
              }
              const renderRecipe = recipe =>{
                  const markup = `
                      <li>
                          <a class="results__link" href="#${recipe.recipe_id}">
                              <figure class="results__fig">
                                  <img src="${recipe.image_url}" alt="${limitRecipeTitle(recipe.title)}">
                              </figure>
                              <div class="results__data">
                                  <h4 class="results__name">${recipe.title}</h4>
                                  <p class="results__author">${recipe.publisher}</p>
                              </div>
                          </a>
                      </li>
                  `;
                  var htmlObject = document.createElement('div');
                  htmlObject.innerHTML = markup;
                  element.searchResultList.insertAdjacentElement('beforeend',htmlObject);
              }
              
              const createButton = (page, type)=>`
              
                  <button class="btn-inline results__btn--${type}" data-goto=${type === 'prev'? page-1 : page+1}>
                  <svg class="search__icon">
                      <use href="img/icons.svg#icon-triangle-${type === 'prev'? 'left' : 'right'}}"></use>
                  </svg>
                  <span>Page ${type === 'prev'? page-1 : page+1}</span>
                  </button>
              `
              const renderButtons = (page, numResults, resultPerPage)=>{
                  const pages = Math.ceil(numResults/resultPerPage);
                  let button;
                  if(page == 1 && pages >1){
                      //button to go to next page
                      button = createButton(page, 'next');
                  }else if(page<pages){
                    //both buttons  
                    button = `
                    ${createButton(page, 'prev')}
                    ${createButton(page, 'next')}`;
              
              
                  }
                  else if (page === pages && pages > 1){
                      //Only button to go to prev page
                      button = createButton(page, 'prev');
                  }
              
                  element.searchResPages.insertAdjacentHTML('afterbegin', button);
              }
              export const renderResults = (recipes, page=1, resultPerPage=10) =>{
                  /*//recipes.foreach(el=>renderRecipe(el))
                  //or foreach will automatically call the render recipes
                  //recipes.forEach(renderRecipe)*/
                  const start = (page-1)*resultPerPage;
                  const end = page * resultPerPage;
                  recipes.slice(start, end).forEach(renderRecipe);
                  renderButtons(page, recipes.length, resultPerPage);
              }
              
              

              文件:Search.js

              export default class Search{
                  constructor(query){
                      this.query = query;
                  }
                  async getResults(){
                      try{
                          const res = await axios(`https://api.com/api/search?&q=${this.query}`);
                          this.result = res.data.recipes;
                          //console.log(this.result);
                      }catch(error){
                          alert(error);
                      }
                  }
              }
              

              文件:Index.js

              onst state = {};
              const controlSearch = async()=>{
                const query = searchView.getInput();
                if (query){
                  state.search = new Search(query); 
                  searchView.clearResults();
                  searchView.clearInput();
                  await state.search.getResults();
                  searchView.renderResults(state.search.result);
                }
              }
              //event listner to the parent object to delegate the event
              element.searchForm.addEventListener('submit', event=>{
                console.log("submit search");
                event.preventDefault();
                controlSearch();
              });
              
              element.searchResPages.addEventListener('click', e=>{
                const btn = e.target.closest('.btn-inline');
                if(btn){
                  const goToPage = parseInt(btn.dataset.goto, 10);//base 10
                  searchView.clearResults();
                  searchView.renderResults(state.search.result, goToPage);
                }
              });
              
              

              【讨论】:

                【解决方案10】:

                只需使用window.nextPageToken 在全局变量中创建和保存页面标记。每次发出请求时将其发送到 API 服务器并让它返回下一个响应,您可以轻松跟踪最后一个令牌。下面是一个如何从搜索结果向前和向后移动的示例。关键是您根据保存的 nextPageToken 发送到 API 的偏移量:

                function getPrev() {
                  var offset = Number(window.nextPageToken) - limit * 2;
                  if (offset < 0) {
                    offset = 0;
                  }
                  window.nextPageToken = offset;
                  if (canSubmit(searchForm, offset)) {
                    searchForm.submit();
                  }
                }
                
                function getNext() {
                  var offset = Number(window.nextPageToken);
                  window.nextPageToken = offset;
                  if (canSubmit(searchForm, offset)) {
                    searchForm.submit();
                  }
                }
                

                【讨论】:

                  【解决方案11】:

                  您可以使用这个最小插件中的代码。 https://www.npmjs.com/package/paginator-js

                  Array.prototype.paginate = function(pageNumber, itemsPerPage){
                    pageNumber   = Number(pageNumber)
                    itemsPerPage = Number(itemsPerPage)
                    pageNumber   = (pageNumber   < 1 || isNaN(pageNumber))   ? 1 : pageNumber
                    itemsPerPage = (itemsPerPage < 1 || isNaN(itemsPerPage)) ? 1 : itemsPerPage
                  
                    var start     = ((pageNumber - 1) * itemsPerPage)
                    var end       = start + itemsPerPage
                    var loopCount = 0
                    var result    = {
                      data: [],
                      end: false
                    }
                  
                    for(loopCount = start; loopCount < end; loopCount++){
                      this[loopCount] && result.data.push(this[loopCount]);
                    }
                  
                    if(loopCount == this.length){
                      result.end = true
                    }
                  
                    return result
                  }
                  

                  【讨论】:

                  • 改变内置插件不是可行的方法
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-04-02
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-04-19
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-04-20
                  相关资源
                  最近更新 更多