js实现列表分页、查询(等细节处置)的功能

js实现列表分页及查询的功能

场景一:

某一天,后端开发同事说:这个列表的数据不是特别多,我一次传给你,你自己处理一下这些数据,OK不OK?

场景二:

项目经理:项目这里要做个列表页,不单独开发接口了,实现一下查询的功能就可以了。

大头答:有获取数据的接口吗?模糊查询还是精确查询?查询条件是多选还是单选?用UI组件库吗?

项目经理答:数据纯手工造,模糊查询嘛,一个或多个查询都可以晒!不合适。

 ······

细想片刻,我擦,还有分页要做?

捋捋思路,不用Element-UI组件库是吧?要实现列表页,主要就是实现分页以及查询噶,根据页码、是否查询来动态渲染页面数据,应该不是太难,好,开干!

需求分析

列表分页倒是没有什么太大的问题,根据设置的当前页大小拆分这个数组返回相对应的数组就行,引入查询之后呢?区别无非在于拆分的这个数组有所变化对吧,这是根据查询生成的一个新的数组,其他按部就班的来就没问题了。

参考Element-UI列表和分页的实现,通常,我们是将当前页、页面大小、查询条件一起返回后端,页面响应对应的数据就完成了。因此,这里我们可以封装一个方法就能实现这一需求,对吧!

功能实现

分页

分页一般来说,主要包括:上下页切换的功能、点击页码跳转某一页的功能以及直达某一页的功能,那目标就是正确的显示当前页的数据以及分页中的页码及其他数据,然后再注意一些其他的细节就可以了。

  1. 创建对应的html结构
<div class="list_page">
   <span class="page_prev" id="page_prev">
   	<a>上一页a>
   span>
   <span class="page_next" id="page_next">
   	<a>下一页a>
   span>
   <span class="page_text">跳转到span>
   <span class="gopage">
   	<input type="text" value="1" id="gopage" name="gopage">
   span>
   <span class="list_page_span">GOspan> div>
 div>

为啥没有页码?查询和不查询的页码肯定是分情况讨论的啊,所以页码由我们动态生成DOM去实现;
2. 生成页码及表格页面

  1. 确定分页大小、总页数
<script>
  	// 页面大小为15条,获取总页数
	window.totalPage = Math.ceil(pageData.length / 15)
<script>
  1. 获取对应分页上的数据
<script>
  	// 先获取当前页第一条数据和最后一条数据角码,进而分割字符串
    var startIndex = (pageIndex - 1) * 15;
    var endIndex = startIndex + 15;
    var tableData = pageData.slice(startIndex, endIndex)
<script>
  1. 页面数据渲染
    渲染数据的时候,咱是否应该处理掉当前页面上的表格数据,因此,首先清空表格里面原有的数据;之后给定表头的列表数据;然后我们就来循环渲染上面我们获取到的tableData;因为我这里的需求是表格是斑马条纹的样式,因此这里做了一个判断,进而得到奇数和偶数两个不同属性的数据;最后填充表格数据,就完成了表格对应的页面。
<script>
  	// 先获取当前页第一条数据和最后一条数据角码,进而分割字符串
    const table = document.getElementById("txl_table")
    table.innerHTML = ''
    var tableHtml = '物品名称所属分类订购电话'
    for (let i = 0; i < tableData.length; i++) {
    if (i % 2 === 0) {
      tableHtml += '' + '' + tableData[i].unitName + ' ' + tableData[i].jobIDName + '' + tableData[i].telephone + '' + ''
      } else {
      tableHtml += '' + '' + tableData[i].unitName +
      ' ' + tableData[i].jobIDName + '' + tableData[i].telephone + '' + ''
      }
    }
    table.innerHTML = tableHtml
	// 给页面直达的span标签赋值,也相当于是显示第几页
	document.getElementById('gopage').value = pageIndex
<script>
  1. 分页数据的渲染
    这里特别说明一下分页数据的渲染:假定我们有200条数据,分页大小为15,那么我们就有14页的数据,页码都要展示出来吗?那肯定是不需要的,展示五个页码就比较合适(如果对当前页页码有样式处理,奇数最为合适),当前页居中,对吧?如果是第九页,那我们就展示第七页、第八页、第九页、第十页、第十一页;第一页的话,就是一到五;第二页的话,也是一到五,因为没有-1页;第三页,也是一到五,且刚好居中满足我们的需求;以此类推,到第十二页的时候,对应的就是十到十四页对吧;再然后呢?为满足咱们的需求,第十三页和第十四页是不是应该只能往前推了呢,即十到十四。因此这里就是三种情况了,因此在渲染分页页面的时候就需要进行相应的一个判断;不过这里还有一种情况我们没有考虑到,如果一共就一页或者两页数据呢?这里即又是一种新的情况。
    因此,实现分页的时候,我们还要考虑四种情况。
    1. 调用同一个方法,因此,每次渲染对应数据的时候,我们应先清空之前的页面数据;
<script>
  // 查找页面上所有ID为“makeSpan”的span标签,然后删除
  var spanElements = document.querySelectorAll('#makeSpan');
  if (spanElements.length > 0) {
    spanElements.forEach(function (element) {
      element.remove();

    });
  }
  pageIndexHtmls = ''
</script>

  1. 判断并创建对应的分页页面结构
    判断的时候,我们始终会对是否为当前页进行一个判断,为减少重复代码,这里封装了一个公共的方法去判断是否为当前页,是,我们就加上“active”的属性值,否,则不添加;
<script>
  // 是否为当前页
  function generatePageIndexHtml(x, pageIndex) {  
    var pageIndexHtml = ''  
    if (x == pageIndex) {  
      pageIndexHtml += '+ x + ')">' + x + '';  
    } else {  
      pageIndexHtml += '+ x + ')">' + x + '';  
    }  
    return pageIndexHtml;  
  }
</script>
<script>
  if(totalPage >= 5) {
    if(totalPage - 2 >= pageIndex && pageIndex >= 4) {
      for (let x = pageIndex - 2; x <= pageIndex + 2; x++) {
        pageIndexHtmls += generatePageIndexHtml(x, pageIndex)
      }
    }

    if(pageIndex > totalPage - 2 && pageIndex > 4) {
      for (let x = totalPage - 4; x <= totalPage; x++) {
        pageIndexHtmls += generatePageIndexHtml(x, pageIndex)
      }
    }
    
    if(pageIndex < 4) {
      for (let x = 1; x <= 5; x++) {
        pageIndexHtmls += generatePageIndexHtml(x, pageIndex)
      }
    }
  } else {
    for (let x = 1; x <= totalPage; x++) {
      pageIndexHtmls += generatePageIndexHtml(x, pageIndex)
    }
  }
  // 在id为page_prev的span标签后添加这段html结构,即切换至上一页的按钮后添加
  document.getElementById('page_prev').insertAdjacentHTML('afterend', pageIndexHtmls);
</script>
  1. 上一页及下一页
    通过监听上一页和下一页是否有点击事件来实现,如果当前页不是第一页,则上一页即自减;反之,下一页也亦是如此;
<script>
    document.getElementById('page_prev').addEventListener('click', function () {
  	  // 获取当前页码
      let currentPage = document.getElementById('gopage').value;
        if (currentPage > 1) {
            currentPage--;
            // makePage()是创建页面的方法,checkInputValues()是判断是否是查询的方法,后面会提到
            makePage(checkInputValues(), currentPage)
        }
    });

    document.getElementById('page_next').addEventListener('click', function () {
      let currentPage = document.getElementById('gopage').value;
        if (currentPage < totalPage) {
            currentPage++;
            makePage(checkInputValues(), currentPage)
        }
    });
</script>
  1. 点击页码跳转
    因为我们在创建页面结构的时候,给每一个页面加上了对应的点击事件,即οnclick=“makePage(checkInputValues(), ’ + x + ')”,这里就不用进行其他的数据处理了;
  2. 页码直达
    在前面,我们给定了一个跳转的标签,即GO,在这里,我们定义一个方法,获取元素的值,从而创建对应的页面,即实现跳转直达某页的需求;这里还可以进行一些细节上的处理,比如说,用户没有输入的时候,点击这里,即仍是刷新当前页的数据,就应该禁用,在这段js代码中加上一个判断就可以了。
<script>
    function goToPage() {
        toPage = document.getElementById('gopage').value
        if(0 < Number(toPage) && Number(toPage) <  totalPage) {      
			makePage(checkInputValues(), Number(toPage))
        }
    }
</script>

查询

在前面的分析中,我们可以知道,查询的数组就是未查询的分页数组过滤之后的新数组,之后创建页面的逻辑也是一样,因此在整体封装创建页面的方法之前,我们可以添加一个字段去判断是否进行了查询,是,就用新数组,否,就用原始的数组。

  1. 创建三个查询条件的输入框,即查询搜索的页面结构;
<table width="100%"  cellspacing="0" cellpadding="0" border="0" class="tablelists topfrom">
  <tbody>
    <tr>
      <th>商品名称:th>
      <td class="pa_l_10"><input type="text" value="" name="SearchKey" id="unitName" class="input2">td>
      <th>所属品类: th>
      <td class="pa_l_10"><input type="text" value="" name="SearchKey" id="jobIDName" class="input2">td>
      <th>订购电话: th>
      <td class="pa_l_10"><input type="text" value="" name="SearchKey" id="telephone" class="input2">td>
      <td style="text-align: center;"><input type="submit" value="搜索" class="btn_submit" onclick="makePage(checkInputValues(), 1)" />td>
    tr>
  tbody>
table>
  1. 是否查询
<script>
	 // 获取输入框是否有值,有的话,就返回true
	 function checkInputValues() {
	     const unitName = document.getElementById('unitName').value;
	     const jobIDName = document.getElementById('jobIDName').value;
	     const telephone = document.getElementById('telephone').value;
	     var hasValues = [unitName, jobIDName, telephone].some(function (value) {
	         return value !== '';
	     });
	     return hasValues;
	 }
</script>
  1. 模糊查询(过滤数组)
<script>
	const unitName = document.getElementById('unitName').value;
    const jobIDName = document.getElementById('jobIDName').value;
    const telephone = document.getElementById('telephone').value;
    const result = array.filter(item => {
      return (item.unitName.includes(unitName) && item.jobIDName.includes(jobIDName) &&
              item.telephone.includes(telephone));
    });
	// 赋值给表格数据
    pageData = result
</script>

完整代码

// 表格样式
  <style>
      .txl_table{ margin-top:20px;}
      .txl_table th{ background:#015fa7; height:40px; text-align:center; color:#fff; font-weight:normal; line-height:40px;}
      .txl_table td{ height:40px; line-height:40px;}
      .txl_table tr.odd{ background:#eef6fc;}
      .txl_table tr.even{ background:#eef6fc;}
      .txl_table tr td{ padding-left:10px;}
      .txl_table tr:hover{ background:#e1effa;}
  </style>
  
  <script>
    // 是否为当前页
  	function generatePageIndexHtml(x, pageIndex) {  
        var pageIndexHtml = ''  
        if (x == pageIndex) {  
            pageIndexHtml += '+ x + ')">' + x + '';  
        } else {  
            pageIndexHtml += '+ x + ')">' + x + '';  
        }  
        return pageIndexHtml;  
    }
  </script>
  
  <script>
    function makePage(isSearch, pageIndex) {
        pageData = []
        if (isSearch) {
            const unitName = document.getElementById('unitName').value;
            const jobIDName = document.getElementById('jobIDName').value;
            const telephone = document.getElementById('telephone').value;
            const result = array.filter(item => {
                return (item.unitName.includes(unitName) && item.jobIDName.includes(jobIDName) &&
                    item.telephone.includes(telephone));
            });
            pageData = result
        } else {
            pageData = array
        }
        // 分页
        window.totalPage = Math.ceil(pageData.length / 15)
        var spanElements = document.querySelectorAll('#makeSpan');
        if (spanElements.length > 0) {
            spanElements.forEach(function (element) {
                element.remove();
              
            });
        }
        pageIndexHtmls = ''
        if(totalPage >= 5) {
          if(totalPage - 2 >= pageIndex && pageIndex >= 4) {
          	for (let x = pageIndex - 2; x <= pageIndex + 2; x++) {
              	pageIndexHtmls += generatePageIndexHtml(x, pageIndex)
            }
          }
          if(pageIndex > totalPage - 2 && pageIndex > 4) {
          	for (let x = totalPage - 4; x <= totalPage; x++) {
                pageIndexHtmls += generatePageIndexHtml(x, pageIndex)
            }
          }
          if(pageIndex < 4) {
          	for (let x = 1; x <= 5; x++) {
                pageIndexHtmls += generatePageIndexHtml(x, pageIndex)
            }
          }
        } else {
        	for (let x = 1; x <= totalPage; x++) {
                pageIndexHtmls += generatePageIndexHtml(x, pageIndex)
            }
        }
        document.getElementById('page_prev').insertAdjacentHTML('afterend', pageIndexHtmls);
        // 列表数据
        var startIndex = (pageIndex - 1) * 15;
        var endIndex = startIndex + 15;
        var tableData = pageData.slice(startIndex, endIndex)
        const table = document.getElementById("txl_table")
        table.innerHTML = ''
        var tableHtml = '商品名称所属品类订购电话'
        for (i = 0; i < tableData.length; i++) {
            if (i % 2 === 0) {
                tableHtml += '' + '' + tableData[i].unitName + ' ' +
                    tableData[i].jobIDName + '' + tableData[i].telephone + '' + ''
            } else {
                tableHtml += '' + '' + tableData[i].unitName +
                    ' ' + tableData[i].jobIDName + '' + tableData[i]
                    .telephone + '' + ''
            }
        }
        table.innerHTML = tableHtml
        document.getElementById('gopage').value = pageIndex
    }
</script>

<script>
    function checkInputValues() {
        const unitName = document.getElementById('unitName').value;
        const jobIDName = document.getElementById('jobIDName').value;
        const telephone = document.getElementById('telephone').value;
        var hasValues = [unitName, jobIDName, telephone].some(function (value) {
            return value !== '';
        });
        return hasValues;
    }
    function goToPage() {
        toPage = document.getElementById('gopage').value;
        if(0 < Number(toPage) && Number(toPage) <  totalPage) {      
			makePage(checkInputValues(), Number(toPage))
        }
    }
</script>
  
  <script>
    // 初始化页面
    let arr = [  
      { unitName: '苹果', jobIDName: '水果', telephone: '028-12345678' }, 
      	······
      { unitName: '电烤箱', jobIDName: '家电', telephone: '028-87654321' }
    ]
    array = [...arr, ...arr, ...arr]
    makePage(checkInputValues(), 1)
  </script>
  
<script>
    document.getElementById('page_prev').addEventListener('click', function () {
      let currentPage = document.getElementById('gopage').value;
        if (currentPage > 1) {
            currentPage--;
            makePage(checkInputValues(), currentPage)  
        }
    });
    document.getElementById('page_next').addEventListener('click', function () {
      let currentPage = document.getElementById('gopage').value;
        if (currentPage < totalPage) {
            currentPage++;
            makePage(checkInputValues(), currentPage)
        }
    });
</script>

你可能感兴趣的:(JavaScript,javascript)