溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JavaScript瀑布流怎么實(shí)現(xiàn)

發(fā)布時(shí)間:2022-02-18 09:06:16 來(lái)源:億速云 閱讀:151 作者:iii 欄目:開(kāi)發(fā)技術(shù)

這篇文章主要介紹“JavaScript瀑布流怎么實(shí)現(xiàn)”,在日常操作中,相信很多人在JavaScript瀑布流怎么實(shí)現(xiàn)問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”JavaScript瀑布流怎么實(shí)現(xiàn)”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

    瀑布流的核心

    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)簽中寫(xiě)入 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)?nbsp;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)?nbsp;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" >
                            <img src="${item.photo.path}" alt="">
                        </div>
                        <div class="contentBox">
                            <p>${item.msg}</p>
                            <p>
                                <span >
                                    <i>點(diǎn)贊</i>${item.like_count}
                                </span>
                                <span >
                                    <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 就要拼接寫(xiě)入最矮的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)簽中 拼接寫(xiě)入 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)簽

    JavaScript瀑布流怎么實(shí)現(xiàn)

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

    JavaScript瀑布流怎么實(shí)現(xiàn)

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

    JavaScript瀑布流怎么實(shí)現(xiàn)

    JavaScript瀑布流怎么實(shí)現(xiàn)

    (4)服務(wù)器配置更改

     運(yùn)行結(jié)果

    JavaScript瀑布流怎么實(shí)現(xiàn)

    到此,關(guān)于“JavaScript瀑布流怎么實(shí)現(xiàn)”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

    向AI問(wèn)一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI