JavaScript瀑布流的實(shí)現(xiàn)你學(xué)會(huì)了嗎
瀑布流的核心
1, 根據(jù) ajax請(qǐng)求的響應(yīng)體結(jié)果 動(dòng)態(tài)渲染生成頁(yè)面
請(qǐng)求地址 請(qǐng)求方式 參數(shù)鍵名 都是 后端程序定義的
前端 只能根據(jù)需求 定義 攜帶的具體的參數(shù)數(shù)據(jù)
響應(yīng)體數(shù)據(jù)是后端程序返回的數(shù)據(jù)結(jié)果
只能獲取數(shù)據(jù)結(jié)果 不能修改數(shù)據(jù)結(jié)果
可以根據(jù) 響應(yīng)體數(shù)據(jù)結(jié)果 動(dòng)態(tài)渲染生成頁(yè)面內(nèi)容
可以使用 三元運(yùn)算符 給標(biāo)簽定義屬性等
2, 瀑布流 再次 發(fā)起請(qǐng)求的判斷依據(jù)
上卷高度 + 視窗窗口高度 + 預(yù)留高度 > 最矮ul占位高度
3, 函數(shù)的節(jié)流
同時(shí)觸發(fā) 多次執(zhí)行 相同的函數(shù)程序
只需要觸發(fā)執(zhí)行 第一次 函數(shù)程序的調(diào)用
原理:
- 定義一個(gè) 開(kāi)關(guān)變量
- 變量?jī)?chǔ)存原始數(shù)據(jù)
執(zhí)行判斷
- 如果 變量 存儲(chǔ)原始數(shù)據(jù) 變量賦值其他數(shù)據(jù)
- 如果 變量 存儲(chǔ)其他數(shù)據(jù) 執(zhí)行 return 終止之后程序的執(zhí)行
當(dāng) 函數(shù)的所有程序都觸發(fā)執(zhí)行結(jié)束
變量 賦值原始值 可以再次觸發(fā) 新的函數(shù)
案例
這里用某糖網(wǎng)站作為案例,調(diào)用某糖網(wǎng)站的接口,仿一個(gè)簡(jiǎn)單的網(wǎng)頁(yè)。
代碼
<!DOCTYPE html>
<html lang="en">
<head>
<!-- 服務(wù)器加載網(wǎng)絡(luò)圖片的meta標(biāo)簽 -->
<meta name="referrer" content="never">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.btn {
width: 300px;
margin: 50px auto;
}
ul,
ol,
li {
list-style: none;
}
img {
display: block;
width: 100%;
height: 100%;
}
a,
a:hover,
a:active {
text-decoration: none;
}
.box {
width: 1200px;
margin: 0 auto;
}
.box::after {
display: block;
content: "";
clear: both;
}
.box ul {
width: 260px;
float: left;
margin: 0 20px;
}
.box ul li {
width: 100%;
display: flex;
flex-direction: column;
border: 2px solid #000;
margin: 0 0 15px 0;
}
.box ul li .imgBox {
width: 100%;
}
.box ul li .contentBox {
width: 100%;
padding: 15px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.box ul li .contentBox p {
display: flex;
justify-content: flex-start;
align-items: center;
}
.box ul li .contentBox p:nth-child(1) {
margin: 10px 0;
}
.box ul li .contentBox p:nth-child(2) {
margin: 10px 0;
}
.box ul li .contentBox p:nth-child(2) span {
margin: 0 10px 0 0;
}
.box ul li .contentBox p:nth-child(2) span i {
margin: 0 10px 0 0;
}
.box ul li .contentBox p:nth-child(3) span:nth-child(1) {
display: block;
width: 40px;
height: 40px;
border-radius: 50%;
overflow: hidden;
margin: 0 10px 0 0;
}
</style>
</head>
<body>
<div class="btn">
<button>美食菜譜</button>
<button>美妝造型</button>
<button>家居生活</button>
<button>人物明星</button>
</div>
<!-- div中的內(nèi)容是 動(dòng)態(tài)生成的 -->
<div class="box"></div>
<script src="../../ajax.js"></script>
<script>
// 定義全局變量 存儲(chǔ)相關(guān)的數(shù)據(jù)信息
let start;
let time;
let keyword;
// 獲取父級(jí)div標(biāo)簽
const oBox = document.querySelector('.box');
// 定義全局變量 存儲(chǔ) 要使用的數(shù)據(jù)
let oUls;
let flag = true;
// 獲取 所有的button按鈕
const oBtns = document.querySelectorAll('button');
// 循環(huán)遍歷 給 所有的button標(biāo)簽 添加 點(diǎn)擊事件
oBtns.forEach(item => {
item.addEventListener('click', function () {
// 默認(rèn)第一次顯示的是從索引下標(biāo)是0開(kāi)始的第一條數(shù)據(jù)
start = 0;
// 獲取關(guān)鍵詞
keyword = this.innerHTML;
// 向 div標(biāo)簽中寫入 4個(gè)ul空標(biāo)簽
oBox.innerHTML = "<ul></ul><ul></ul><ul></ul><ul></ul>";
// 獲取 所有的ul標(biāo)簽對(duì)象
oUls = oBox.querySelectorAll('ul');
// 調(diào)用執(zhí)行 async await 和 promise執(zhí)行的 ajax請(qǐng)求
setPage();
})
})
// 定義 頁(yè)面滾動(dòng)監(jiān)聽(tīng)事件
window.addEventListener('scroll', function () {
// 獲取 占位數(shù)據(jù)數(shù)值
// 頁(yè)面上卷高度
let scrollTop = document.documentElement.scrollTop;
// 視窗窗口占位高度
let winHeight = document.documentElement.clientHeight;
// 設(shè)定預(yù)留高度
let height = 500;
// 獲取最矮ul標(biāo)簽對(duì)象
// 循環(huán)結(jié)束 minUl 變量中 存儲(chǔ) 最矮ul標(biāo)簽對(duì)象
let minUl = oUls[0];
for (let i = 0 + 1; i <= oUls.length - 1; i++) {
// 如果 minUl 變量中 存儲(chǔ)的 ul標(biāo)簽 高度 大于 oUls[i]循環(huán)遍歷的ul標(biāo)簽的占位
// 變量minUl 中 存儲(chǔ) oUls[i] 循環(huán)遍歷的ul標(biāo)簽
if (minUl.offsetHeight > oUls[i].offsetHeight) {
minUl = oUls[i];
}
}
// 執(zhí)行判斷
if (scrollTop + winHeight + height > minUl.offsetHeight) {
// 再次發(fā)起請(qǐng)求 動(dòng)態(tài)渲染生成新的頁(yè)面內(nèi)容
/*
因?yàn)?scroll事件 鼠標(biāo)滾動(dòng)一次 多次觸發(fā) scroll事件
也就是 鼠標(biāo)滾動(dòng)一次 多次觸發(fā)執(zhí)行 setPage() 函數(shù)
也就是 鼠標(biāo)滾動(dòng)一次 多次觸發(fā)執(zhí)行 新的 ajax請(qǐng)求
因?yàn)?ajax請(qǐng)求是異步程序 結(jié)果就是 多次觸發(fā)的ajax請(qǐng)求 執(zhí)行的是相同的請(qǐng)求參數(shù)
獲取的 響應(yīng)體結(jié)果 是 相同的響應(yīng)體結(jié)果
實(shí)際項(xiàng)目中 多次請(qǐng)求 只需要執(zhí)行 第一次請(qǐng)求
*/
// 判斷變量?jī)?chǔ)存的數(shù)據(jù) 防止多次調(diào)用函數(shù)
if (flag) {
flag = false;
} else {
return;
}
// 再次調(diào)用函數(shù) 發(fā)起新的請(qǐng)求 動(dòng)態(tài)渲染生成新的頁(yè)面
setPage();
}
})
// 使用 async 定義 異步請(qǐng)求函數(shù)程序
async function setPage() {
// 獲取 時(shí)間對(duì)象 和 時(shí)間戳
const t = new Date();
time = t.getTime();
// 發(fā)起請(qǐng)求時(shí) 根據(jù)需求 設(shè)定 ajax請(qǐng)求攜帶的參數(shù)數(shù)據(jù)
// response中存儲(chǔ)的是響應(yīng)體數(shù)據(jù)
const response = JSON.parse(await myPromiseAjax('/dt', 'get', `include_fields=top_comments%2Cis_root%2Csource_link%2Citem%2Cbuyable%2Croot_id%2Cstatus%2Clike_count%2Csender%2Calbum%2Creply_count&filter_id=${keyword}&start=${start}&_=${time}`));
console.log(response);
// 給下一次 請(qǐng)求 賦值起始數(shù)據(jù)的索引下標(biāo)
start = response.data.next_start;
// 獲取 24條數(shù)據(jù)的數(shù)組
const arr = response.data.object_list;
// 循環(huán)遍歷 數(shù)組中的24個(gè)單元
arr.forEach(item => {
// 根據(jù)數(shù)組單元的數(shù)據(jù) 生成 li標(biāo)簽
let str = `
<li>
<div class="imgBox" style="height:${260 * item.photo.height / item.photo.width}px">
<img src="${item.photo.path}" alt="">
</div>
<div class="contentBox">
<p>${item.msg}</p>
<p>
<span style="${item.like_count === 0 ? 'display:none' : ''}">
<i>點(diǎn)贊</i>${item.like_count}
</span>
<span style="${item.favorite_count === 0 ? 'display:none' : ''}">
<i>收藏</i>${item.favorite_count}
</span>
</p>
<p>
<span>
<img src="${item.sender.avatar}" alt="">
</span>
<span>
${item.sender.username} <br>
發(fā)布到 <a href="JavaScript:;">${item.album.name}</a>
</span>
</p>
</div>
</li>`;
// 每生成一個(gè)li 就要拼接寫入最矮的ul標(biāo)簽中
// 獲取最矮的ul標(biāo)簽
let minUl = oUls[0];
for (let i = 0 + 1; i <= oUls.length - 1; i++) {
// 如果 minUl 變量中 存儲(chǔ)的 ul標(biāo)簽 高度 大于 oUls[i]循環(huán)遍歷的ul標(biāo)簽的占位
// 變量minUl 中 存儲(chǔ) oUls[i] 循環(huán)遍歷的ul標(biāo)簽
if (minUl.offsetHeight > oUls[i].offsetHeight) {
minUl = oUls[i];
}
}
// 循環(huán)結(jié)束minUl 中 存儲(chǔ)的是 最矮的ul標(biāo)簽對(duì)象
// 向 最矮的ul標(biāo)簽中 拼接寫入 li標(biāo)簽
minUl.innerHTML += str;
})
// 當(dāng)請(qǐng)求執(zhí)行結(jié)束 當(dāng)新的頁(yè)面內(nèi)容生成完畢
// 可以再次發(fā)起新的請(qǐng)求 給 變量賦值原始數(shù)據(jù)
flag = true;
}
</script>
</body>
</html>ajax代碼
// 封裝一個(gè)promise程序執(zhí)行 ajax請(qǐng)求
// 參數(shù)1 請(qǐng)求的url地址
// 參數(shù)2 請(qǐng)求的方式
// 參數(shù)3 攜帶的參數(shù)怇
function myPromiseAjax( url , type = 'get' , data = '' ){
// 創(chuàng)建一個(gè) promise 對(duì)象
const p = new Promise(function( fulfilled , rejected ){
// 執(zhí)行異步ajax請(qǐng)求
const xhr = new XMLHttpRequest() ;
if( type.toLowerCase() === 'get' ){
// get請(qǐng)求方式
xhr.open( 'get' , `${url}?${data}` );
xhr.send();
}else{
// post請(qǐng)求方式
xhr.open( 'post' , url );
xhr.setRequestHeader('Content-Type' , 'application/x-www-form-urlencoded');
xhr.send(data);
}
// 接收 請(qǐng)求結(jié)果
xhr.onreadystatechange = function(){
// 當(dāng) ajax狀態(tài)碼是 4 時(shí) 判斷 http狀態(tài)碼
if( xhr.readyState === 4 ) {
// 如果 http狀態(tài)碼 是 200 - 299
if( /^2\d{2}$/.test( xhr.status ) ){
// 請(qǐng)求成功
fulfilled( xhr.response );
}else if( /^(4|5)\d{2}$/.test( xhr.status ) ){
// 請(qǐng)求失敗
rejected( xhr.statusText );
}
}
}
});
// return 返回這個(gè)promise對(duì)象
return p;
}注意點(diǎn)
(1)服務(wù)器加載網(wǎng)絡(luò)圖片的meta標(biāo)簽

(2)瀑布流執(zhí)行的判斷依據(jù)

(3)函數(shù)的節(jié)流


(4)服務(wù)器配置更改
運(yùn)行結(jié)果

總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
兩個(gè)listbox實(shí)現(xiàn)選項(xiàng)的添加刪除和搜索
listbox竟然可以實(shí)現(xiàn)選項(xiàng)的添加刪除和搜索不可思議吧,至于采用什么樣的方法實(shí)現(xiàn)的,具體代碼祥看本文嘍,或許可以幫助到你2013-03-03
SpringMVC+bootstrap table實(shí)例詳解
本文通過(guò)實(shí)例給大家介紹了SpringMVC+bootstrap-table,需要的朋友可以參考下2017-06-06
JavaScript組件焦點(diǎn)與頁(yè)內(nèi)錨點(diǎn)間傳值的方法
這篇文章主要介紹了JavaScript組件焦點(diǎn)與頁(yè)內(nèi)錨點(diǎn)間傳值的方法,涉及輸入框與錨點(diǎn)的操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02
點(diǎn)擊按鈕彈出模態(tài)框的一系列操作代碼實(shí)例
這篇文章主要介紹了js彈出模態(tài)框方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03
js面向?qū)ο蠓庋b級(jí)聯(lián)下拉菜單列表的實(shí)現(xiàn)步驟
這篇文章主要介紹了js面向?qū)ο蠓庋b級(jí)聯(lián)下拉菜單列表的實(shí)現(xiàn)步驟,幫助大家更好的理解和使用JavaScript,感興趣的朋友可以了解下2021-02-02
bootstrap table動(dòng)態(tài)加載數(shù)據(jù)示例代碼
本篇文章主要介紹了bootstrap table動(dòng)態(tài)加載數(shù)據(jù)示例代碼,可以實(shí)現(xiàn)點(diǎn)擊選擇按鈕,彈出模態(tài)框,加載出關(guān)鍵詞列表,有興趣的可以了解一下。2017-03-03
靜態(tài)的動(dòng)態(tài)續(xù)篇之來(lái)點(diǎn)XML
靜態(tài)的動(dòng)態(tài)續(xù)篇之來(lái)點(diǎn)XML...2006-12-12

