关于前端:js之页面列表加载常用方法总结

40次阅读

共计 5567 个字符,预计需要花费 14 分钟才能阅读完成。

导语:最近因为一些事件须要解决,所以没来得及写技术总结了。明天终于能够坐下来好好的梳理一下脉络,说一下那个在日常前端开发过程中,罕用到的页面列表加载的办法总结。这里介绍三种办法,别离是分页加载、按钮加载以及滚动加载。

目录

  • 办法简介
  • 代码实现
  • 成果预览

办法简介

在日常的前端开发过程中,咱们常常会碰到列表很长,不可能齐全显示进去,所以就要进行分页,每页固定显示几条,而后上面是页数,点到哪页显示哪页的内容。

除了常见的分页加载外,还要点击按钮加载,这种加载办法就是不须要点击下一页这种了,间接点击按钮往第一页的前面补高低一页的内容,十分不便。

除了以上两种,滚动加载也是用的比拟多的一种列表加载办法,上面就这三种办法做一下总结演绎,不便须要的小伙伴们应用。

封装实现

上面就对三种办法别离做一下原理解析和办法实现。

上面的列表应用了 JSONPlaceholder 站点上的一些数据作为列表起源。

分页加载

当页面的需要是要显示一个列表或者表格,总数很多放不下,这时候能够把全副的数据分成多页,每页显示固定的条数,计算出总页数,而后渲染一下就能够了。

  • 页面布局
<div class="wrap">
    <ul id="list"></ul>
    <ul id="pages"></ul>
</div>
.wrap {
    max-width: 960px;
    margin: 0 auto;
    padding: 15px 0;
}

.wrap li {
    padding: 5px 0;
    list-style: square;
}

.wrap li h3,
.wrap li p {text-transform: capitalize;}

.wrap li h3:hover {
    color: #f00;
    cursor: pointer;
}

#pages li {
    display: inline-block;
    margin-right: 10px;
    list-style: none;
}

#pages button {
    width: auto;
    min-width: 40px;
    height: 40px;
    background: #fff;
    box-shadow: 0 0 5px #fff;
    border: 1px solid #ccc;
    border-radius: 5px;
    font-size: 16px;
}

#pages button:hover,
#pages button.active {
    color: #fff;
    border-color: #f00;
    background: #f00;
    cursor: pointer;
}

#pages button.dis {cursor: no-drop;}

.wrap .loading {
    line-height: 70vh;
    text-align: center;
    list-style: none;
}

.wrap .nodata {
    list-style: none;
    text-align: center;
}
  • 定义变量
let datas = [], // 分组列表
current = 1, // 当前页
pages = 0, // 总页数
total = 0, // 总数
listElem = document.getElementById('list'), // 列表内容
pageElem = document.getElementById('pages'); // 页数按钮 
  • 解决数据

咱们应用 axios 来获取 json 数据,模仿抓取接口的状况。

// 获取列表
async function getList (page = 1) {let res = await axios.get('https://jsonplaceholder.typicode.com/posts');
    if (res.status === 200) {let data = sliceData(res.data);
        pages = data.pages;
        total = res.data.length;
        datas = [...data.list];
        return {
            code: 200,
            msg: 'get_succ',
            data: {list: data.list[page-1],
                current: page,
                pages: data.pages,
                total: list.length,
            }
        }
    }
}

写一个切割数组的办法,分成等份的数组。

// 解决数据
function sliceData (list) {let newArr = [],step = 10,pages = Math.ceil(list.length/10);
    for (let i = 0; i < list.length; i+=step) {let item = list.slice(i, i+step);
        newArr.push(item);
    }
    return {
        list: newArr,
        pages,
    };
}
  • 显示列表
showList(current);

// 显示列表
async function showList (current) {
    let data = null;
    listElem.innerHTML = '';
    listElem.innerHTML = '<li class="loading"> 加载中...</li>';
    if (datas && datas.length) {
        data = {
            code: 200,
            msg: 'get_succ',
            data: {list: datas[current-1],
                current: current,
                pages,
                total,
            }
        }
    } else {data = await getList(current);
    }
    if (data.code === 200) {
        let list = data.data.list;
        if (list && list.length) {
            let liStr = '',pageStr ='';
            for (const item of list) {
                liStr += `<li>
                    <h3>${item.title}</h3>
                    <p>${item.body}</p>
                </li>`;
            }
            
            setTimeout(() => {listElem.innerHTML = liStr;}, 1000);

            if (pageElem.innerText === '') {for (let i = 0; i < data.data.pages; i++) {pageStr += `<li><button class="page" data-id="${i+1}">${i+1}</button></li>`
                }
                pageElem.innerHTML = `
                <li><button id="start" data-id="1"> 首页 </button></li>
                <li><button id="prev"> 上一页 </button></li>
                ${pageStr}
                <li><button id="next"> 下一页 </button></li>
                <li><button id="end" data-id="${data.data.pages}"> 尾页 </button></li>`;
                showHighLight(current);
                addClick();}
        } else {listElem.innerHTML = '<li class="nodata"> 暂无数据 </li>';}
    }
}
  • 增加点击事件
// 增加点击
function addClick () {let btns = document.querySelectorAll('#pages li button');
    for (const item of btns) {item.addEventListener('click', toggleList, false);
    }
}
  • 切换页面内容
// 切换页面
function toggleList (event) {  
    let id = event.target.dataset.id,
    bid = event.target.id;
    if (id) {current = Number(id);
    }
    if (bid == 'prev') {if (current <= 1) {current = 1;} else {current--;}
    } else if (bid == 'next') {if (current >= pages) {current = pages;} else {current++;}
    }
    showHighLight(current, bid);
    showList(current);
}
  • 显示高亮
// 显示高亮
function showHighLight (current, bid) {let btns = document.querySelectorAll('.page'),
    startBtn = document.getElementById('start'),
    endBtn = document.getElementById('end');
    for (const item of btns) {item.className = 'page';}
    btns[current-1].className = 'page active';
    startBtn.className = current == 1 ? 'active dis' : '';
    endBtn.className = current == pages ? 'active dis' : '';
}

其中渲染好页面后,还加了一个定时器是模仿从服务器获取数据期待过程的成果,真实情况下不须要这样。

按钮加载

按钮加载的办法和下面的类似,也就是分页那块改成一个按钮了,一直在现有的列表中增加新的列表内容,其余和分页加载没有太大区别。

  • 页面构造
<div class="wrap">
    <ul id="list"></ul>
    <p class="loadmore"> 加载中...</p>
    <p class="more-box">
        <button id="more"> 加载更多 </button>
    </p>
</div>
  • 页面丑化
.more-box {text-align: center;}

#more {
    padding: 10px;
    background: none;
    border: 1px solid #ccc;
    border-radius: 5px;
}

#more:hover {
    cursor: pointer;
    border-color: #f00;
    background-color: #f00;
    color: #fff;
}

.loadmore {text-align: center;}

.hide {display: none;}
  • 获取变量
let loadMore = document.querySelector('.loadmore'),
moreBtn = document.getElementById('more');
  • 点击加载更多
// 增加点击
moreBtn.addEventListener('click', addList, false);

// 切换页面
function addList () {if (current < pages) {
        current+=1;
        showList(current);
    } else {moreBtn.innerText = '没有更多了';}
}
  • 显示页面

在原有的显示列表办法根底上批改几处就好了。

// 显示列表
async function showList (current) {
    let data = null;
    loadMore.className = 'loadmore';
    if (datas && datas.length) {
        data = {
            code: 200,
            msg: 'get_succ',
            data: {list: datas[current-1],
                current: current,
                pages,
                total,
            }
        }
    } else {data = await getList(current);
    }
    if (data.code === 200) {
        let list = data.data.list;
        if (list && list.length) {
            let liStr = '',pageStr ='';
            for (const item of list) {
                liStr += `<li>
                    <h3>${item.title}</h3>
                    <p>${item.body}</p>
                </li>`;
            }

            listElem.innerHTML += liStr;

        } else {listElem.innerHTML = '<li class="nodata"> 暂无数据 <li>';}

        
        setTimeout(() => {loadMore.className = 'loadmore hide';}, 1000);
    }
}

滚动加载

滚动加载就是在页面滚动到底部后主动增加新的一页内容到以后列表前面,每次滚动依据计算动静增加内容。

就是在按钮加载的根底上更改而来的,具体的原理是当文档的到顶部的高度加上文档的可视化高度大于文档的滚动高度的时候就加载页面。

  • 页面构造
<div class="wrap">
    <ul id="list"></ul>
    <p class="loadmore"> 加载中...</p>
</div>
  • 滚动判断
document.addEventListener('scroll', checkScroll, false);
function checkScroll () {  
    let scrollTop = document.documentElement.scrollTop,
    clientHei = document.documentElement.clientHeight,
    scrollHeight = document.documentElement.scrollHeight;
    if (scrollTop + clientHei >= scrollHeight) {addList();
    }
}

// 切换页面
function addList () {if (current < pages) {
        current+=1;
        showList(current);
    } else {loadMore.innerText = '没有更多了';}
}

成果预览

  • 分页加载

在线预览

  • 按钮加载

在线预览

  • 滚动加载

在线预览

最初的话

以上就是我在日常开发过程中的用的几种加载的办法,如果有什么问题,欢送邮箱分割我。

正文完
 0