JavaScript - 使用纯Js实现动态分页

3
我正在尝试使用纯JavaScript创建动态分页。我遇到了一些障碍,例如尝试创建动态分页并将页面数字链接到显示正确项目的位置。这是我正在努力解决的代码,请查看Codepen以查看整个项目。
初始变量:
var currentPage = 1;
var numPages = 0;
var studentsPerPage = 10;
var index;

使用JavaScript创建分页:

var paginationFilter = function pageFilter (nbOfEntries) {
var pagination = document.createElement('div');
var ulList = document.createElement('ul');
var liList = document.createElement('li');
var pageLink = document.createElement('a');

pagination.setAttribute("class", "pagination");
pageLink.setAttribute("class", "navlink");
pageLink.setAttribute("href", "#");

pagination.appendChild(ulList);
ulList.appendChild(liList);
liList.appendChild(pageLink);

return pagination;  };

这里是我的函数,用于查找学生名单的长度,计算创建页面的数量,隐藏所有元素并仅显示列表中前10个项目。其他项目应在下一页上显示。
var numberOfStudents = function () {
var numberOfStudents = eachStudent.length;
return (numberOfStudents);}

//Finding the number of pages
var numberOfPages = function () {
    var numberOfPages = parseInt(numberOfStudents() / studentsPerPage);
    if ( numberOfStudents() % studentsPerPage > 0 ){
        numPages += 1;
    }
    return numberOfPages;
}
//Hiding all the students
var hideAll = function () {
    for (var i = 0; i < numberOfStudents(); i++) {
        eachStudent[i].style.display = "none";
    }
};

//Display only the 10 first items on the page
function showStudents (number) {
    for (var i = 0; i < studentsPerPage; i++) {
        index = number * studentsPerPage - studentsPerPage + i;
        eachStudent[index].style.display = "block";
        console.log(index);
    } 
};



function createPages () {
    for (var i = 0; i <= numberOfPages(); i++) {
        page.appendChild(paginationFilter());
        var navlink = document.getElementsByClassName(".navlink");
        var linkText = document.createTextNode(i);
        //i'm trying to append the node to the link in order to create the pagination links dynamically but it's not working...
        navlink.appendChild('linkText');
        console.log(linkText);
    }
};

我在想如何根据列表中的项目数量动态创建分页。这些项目也是动态过滤的,因此页面数量需要实时更新。

链接到示例:http://codepen.io/Delano83/pen/XjYxkQ

欢迎对我的代码进行任何评论或建议!


为什么要重复造轮子?尝试使用Bootstrap或像这样的jQuery插件... http://flaviusmatis.github.io/simplePagination.js/ - bflemi3
我只需要纯JS :)不过还是谢谢你的建议! - delano
2个回答

2

试试这个纯JavaScript实现的Codepen示例。

https://codepen.io/karpovsystems/pen/fFHxK

注意:这不是我的代码,只是在codepen上找到的。

var Pagination = {

    code: '',

    // --------------------
    // Utility
    // --------------------

    // converting initialize data
    Extend: function(data) {
        data = data || {};
        Pagination.size = data.size || 300;
        Pagination.page = data.page || 1;
        Pagination.step = data.step || 3;
    },

    // add pages by number (from [s] to [f])
    Add: function(s, f) {
        for (var i = s; i < f; i++) {
            Pagination.code += '<a>' + i + '</a>';
        }
    },

    // add last page with separator
    Last: function() {
        Pagination.code += '<i>...</i><a>' + Pagination.size + '</a>';
    },

    // add first page with separator
    First: function() {
        Pagination.code += '<a>1</a><i>...</i>';
    },



    // --------------------
    // Handlers
    // --------------------

    // change page
    Click: function() {
        Pagination.page = +this.innerHTML;
        Pagination.Start();
    },

    // previous page
    Prev: function() {
        Pagination.page--;
        if (Pagination.page < 1) {
            Pagination.page = 1;
        }
        Pagination.Start();
    },

    // next page
    Next: function() {
        Pagination.page++;
        if (Pagination.page > Pagination.size) {
            Pagination.page = Pagination.size;
        }
        Pagination.Start();
    },



    // --------------------
    // Script
    // --------------------

    // binding pages
    Bind: function() {
        var a = Pagination.e.getElementsByTagName('a');
        for (var i = 0; i < a.length; i++) {
            if (+a[i].innerHTML === Pagination.page) a[i].className = 'current';
            a[i].addEventListener('click', Pagination.Click, false);
        }
    },

    // write pagination
    Finish: function() {
        Pagination.e.innerHTML = Pagination.code;
        Pagination.code = '';
        Pagination.Bind();
    },

    // find pagination type
    Start: function() {
        if (Pagination.size < Pagination.step * 2 + 6) {
            Pagination.Add(1, Pagination.size + 1);
        }
        else if (Pagination.page < Pagination.step * 2 + 1) {
            Pagination.Add(1, Pagination.step * 2 + 4);
            Pagination.Last();
        }
        else if (Pagination.page > Pagination.size - Pagination.step * 2) {
            Pagination.First();
            Pagination.Add(Pagination.size - Pagination.step * 2 - 2, Pagination.size + 1);
        }
        else {
            Pagination.First();
            Pagination.Add(Pagination.page - Pagination.step, Pagination.page + Pagination.step + 1);
            Pagination.Last();
        }
        Pagination.Finish();
    },



    // --------------------
    // Initialization
    // --------------------

    // binding buttons
    Buttons: function(e) {
        var nav = e.getElementsByTagName('a');
        nav[0].addEventListener('click', Pagination.Prev, false);
        nav[1].addEventListener('click', Pagination.Next, false);
    },

    // create skeleton
    Create: function(e) {

        var html = [
            '<a>&#9668;</a>', // previous button
            '<span></span>',  // pagination container
            '<a>&#9658;</a>'  // next button
        ];

        e.innerHTML = html.join('');
        Pagination.e = e.getElementsByTagName('span')[0];
        Pagination.Buttons(e);
    },

    // init
    Init: function(e, data) {
        Pagination.Extend(data);
        Pagination.Create(e);
        Pagination.Start();
    }
};



/* * * * * * * * * * * * * * * * *
* Initialization
* * * * * * * * * * * * * * * * */

var init = function() {
    Pagination.Init(document.getElementById('pagination'), {
        size: 30, // pages size
        page: 1,  // selected page
        step: 3   // pages before and after current
    });
};

document.addEventListener('DOMContentLoaded', init, false);

你能简要解释一下这段代码如何帮助我筛选出10个项目的页面吗?谢谢! - delano

1

代码并不复杂。JS 代码少于100行↓。

<!-- CSS is not essential. You can ignore it. -->
<style> 
  :root { /* https://developer.mozilla.org/en-US/docs/Web/CSS/--* */
    --color-radial-inside: #ff2200;
    --color-radial-outside: #343232;
  }

  html {
    height: 100%;
    width: 100%;
    background-image: -webkit-radial-gradient(contain, var(--color-radial-inside, #F2F2F2), var(--color-radial-outside, #635e5e));
  }

  body {
    margin: auto;
    height: 100%;
    width: 100%;
    text-align: center;
    font-family: Arial, sans-serif;
  }

  body:before {
    content: '';
    display: inline-block;
    width: 0;
    height: 100%;
    vertical-align: middle;
  }

  #pagination {
    display: inline-block;
    vertical-align: middle;
    border-radius: 0.25rem;
    padding: .1rem .2rem .3rem .2rem;
    border-top: .1rem solid #AEAEAE;
    border-bottom: .1rem solid #FFFFFF;
    background-color: #DADADA;
    background-image: -webkit-linear-gradient(top, #DBDBDB, #E2E2E2);
  }

  #pagination a, #pagination i {
    display: inline-block;
    vertical-align: middle;
    width: 1.375rem;
    color: #7D7D7D;
    text-align: center;
    font-size: 0.625rem;
    padding: .3rem 0 .2rem 0;
    user-select: none;
  }

  #pagination a {
    margin: 0 .2rem 0 .2rem;
    border-radius: .4rem;
    border: .1rem solid #E3E3E3;
    cursor: pointer;
    box-shadow: inset 0 .1rem 0 0 #FFF, 0 .1rem .2rem #666;
    text-shadow: 0 .1rem .1rem #FFF;
    background-color: #E6E6E6;
    background-image: -webkit-linear-gradient(top, #F3F3F3, #D7D7D7);
  }

  #pagination i {
    margin: 0 .3rem 0 .3rem;
  }

  #pagination a.current {
    border: .1rem solid #E9E9E9;
    box-shadow: 0 .1rem .1rem #999;
    background-color: #DFDFDF;
    background-image: -webkit-linear-gradient(top, #D0D0D0, #EBEBEB);
  }
</style>

<body>
<div id="pagination"> <!-- id is for CSS only -->
  <!-- here is a sample that we want to create as below
  <a>◄</a>
  <span>
    <a>1</a><i>...</i><a>2</a><a class="current">3</a><a>4</a><i>...</i><a>5</a>
  </span>
  <a>►</a>
  -->
</div>
</body>

<script type="module">
  export class Pagination {
    /**
     * @param {Array} data
     * @param {Number} step Before and after current
     * @param {Number} selectedPage Selected page
     */
    constructor(data, step = 1, selectedPage = 1) {
      this.data = data || []
      this.size = this.data.length // Pages size
      this.page = selectedPage
      this.step = step
    }

    Build(targetElem) {
      const htmlFrag = document.createRange().createContextualFragment(`
<a>&#9668;</a>
<span></span>
<a>&#9658;</a>
`)// &#9668; ◄ previous button  |  &#9658; ► next button

      const frag = htmlFrag.querySelector(`span`)

      // Calculate the startPage and endPage.
      let startPage = this.page - this.step
      let endPage = this.page + this.step

      if (startPage <= 0) {
        endPage += -startPage + 1
        startPage = 1
      }

      if (endPage >= this.size) {
        startPage = Math.max(startPage - (endPage - this.size), 1)
        endPage = this.size
      }

      // first
      if (startPage > 1) {
        frag.appendChild(document.createRange().createContextualFragment(
          `<a ${this.page === 1 ? 'class="current"' : ''}>1</a><i>...</i>`)
        )
      }

      // middle
      for (let page = startPage; page <= endPage; ++page) {
        frag.appendChild(document.createRange().createContextualFragment(
          `<a ${this.page === page ? 'class="current"' : ''}>${page}</a>`
        ))
      }

      // last
      if (endPage < this.size) {
        frag.appendChild(document.createRange().createContextualFragment(
          `<i>...</i><a ${this.page === this.size ? 'class="current"' : ''}>${this.size}</a>`
        ))
      }

      // middle "a" click
      htmlFrag.querySelectorAll(`span a`).forEach(aElem => {
        aElem.addEventListener('click', () => {
          this.page = +aElem.innerText
          this.Build(targetElem)
        })
      })

      // Prev and next click
      const [aPrev, ...others] = htmlFrag.querySelectorAll(`a`)
      aPrev.addEventListener(`click`, () => {
        this.page--
        if (this.page < 1) {
          this.page = 1
        }
        this.Build(targetElem)
      })

      // next
      others.at(-1).addEventListener(`click`, () => {
        ++this.page
        if (this.page > this.size) {
          this.page = this.size
        }
        this.Build(targetElem)
      })

      targetElem.innerHTML = "" // clear
      targetElem.append(htmlFrag)
    }
  }

  window.onload = () => {
    const testData = [...new Array(100).keys()]
    const startPage = 2
    const step = 3
    const pagination = new Pagination(testData, step, startPage)
    pagination.Build(document.querySelector(`div`))
  }

</script>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接