最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

js+CSS簡(jiǎn)單實(shí)現(xiàn)瀑布流布局

 更新時(shí)間:2023年11月21日 10:59:18   作者:sherlockkid7  
瀑布流布局,是一種視覺(jué)表現(xiàn)為參差不齊的多欄布局,常用于內(nèi)容以圖片為主的頁(yè)面展示,本文將使用css和js兩種方式來(lái)實(shí)現(xiàn)瀑布流布局,需要的可以參考下

前言

瀑布流布局,是一種視覺(jué)表現(xiàn)為參差不齊的多欄布局。常用于內(nèi)容以圖片為主的頁(yè)面展示,圖片等寬不等高,每行從左到右排滿后,后面的元素依次添加至短的一列其后。隨著頁(yè)面向下滾動(dòng),還會(huì)不斷加載數(shù)據(jù)并添加到當(dāng)前尾部,視覺(jué)上顯得錯(cuò)落有致不拘一格。今天使用css和js兩種方式來(lái)實(shí)現(xiàn)瀑布流布局

css實(shí)現(xiàn)瀑布流布局

該方式實(shí)現(xiàn)的瀑布流布局其中的內(nèi)容數(shù)據(jù)是固定的,主要利用了 CSS 的多列屬性 columns

頁(yè)面結(jié)構(gòu):創(chuàng)建容器container,該容器包裹所有用于展示的元素item(圖片和標(biāo)題)

  <div class="container">
    <div class="item">
      <img src="..."/>
      <h2>...</h2>
    </div>
    ...
</div>

給容器container設(shè)置寬度,并居中顯示;控制其中的內(nèi)容分成3列columns: 3;,列與列之間的距離為20pxcolumn-gap: 20px;

每個(gè)item元素,設(shè)置屬性break-inside: avoid;, 避免在多列布局中元素內(nèi)容被分割(元素的內(nèi)容被自動(dòng)斷開(kāi),圖片在一列尾部,文字在下一列的頭部)

.container {
  width: 1200px;
  margin: 20px auto;
  columns: 3;
  column-gap: 20px;
}

.container .item {
  width: 100%;
  break-inside: avoid;
  margin-bottom: 20px;
}
.container .item img{
  width: 100%;
}

小結(jié):根據(jù)上圖可以看出CSS的多列布局實(shí)現(xiàn)的瀑布流是從上到下,再?gòu)淖蟮接业捻樞蚺帕性?,適用于對(duì)于元素順序沒(méi)有要求,且元素?cái)?shù)據(jù)固定的情況

js實(shí)現(xiàn)瀑布流布局

思路:

每個(gè)元素使用絕對(duì)定位的方式,動(dòng)態(tài)的設(shè)置相應(yīng)的top,left值進(jìn)行排列,先計(jì)算一行能夠容納幾列元素,第一行元素直接設(shè)置top為0,left為索引乘以(元素寬度 + 間隙)進(jìn)行排列,后面的元素排列,需要找出所有列中高度最小的那一列,將元素添加至高度最小的那一列后面,直至所有元素添加完畢。

創(chuàng)建一個(gè)容器container,用于存放展示的元素。并設(shè)置css為相對(duì)定位,其中展示的元素為絕對(duì)定位

<div id="container"></div>

計(jì)算頁(yè)面一行能容納幾列元素

列數(shù) = 頁(yè)面的寬度 / (元素的寬度+元素之間的間隙 ) column = pageWidth / (itemWidth + gap);

注:頁(yè)面的寬度這里設(shè)置的是body的寬度(使用css控制了最大寬度和最小寬度)

創(chuàng)建createElement函數(shù),用來(lái)動(dòng)態(tài)創(chuàng)建組成瀑布流的元素塊(包含圖片和標(biāo)題),并在請(qǐng)求數(shù)據(jù)成功后調(diào)用添加到頁(yè)面中,并進(jìn)行瀑布流布局

function createElement(itemData) {
  return new Promise((resolve, reject) => {
    let div = document.createElement('div')
    div.innerHTML = `...`
    div.className = 'item'
    // 監(jiān)聽(tīng)圖片的load事件
    div.querySelector('img').addEventListener('load', () => {
      resolve(div)
    })
  })
}

// 獲取喵咪的數(shù)據(jù)
let page = 1  //請(qǐng)求數(shù)據(jù)的頁(yè)碼
let isReq = false  //設(shè)置節(jié)流閥,處于請(qǐng)求過(guò)程中,則不再請(qǐng)求數(shù)據(jù)
function loadNewData() {
  if (isReq) return
  isReq = true
  getData()
    .then(data => {
      // 處理新的數(shù)據(jù)
      let items = data
      let promises = items.map(item => createElement(item))
      Promise.all(promises).then(nodes => {
        let frag = document.createDocumentFragment()
        isReq = false
        page++
        nodes.forEach(node => {
          frag.appendChild(node)
          Node.push(node)
        })
        document.getElementById('container').appendChild(frag)
        waterfall(Node)
      })
    })
    
}

注:遇到獲取元素塊高度不正確的問(wèn)題

因?yàn)閳D片可能還沒(méi)有完全加載,獲取的元素塊高度就只是h4標(biāo)簽的高度。因此需要在圖片加載完成后再獲取元素的高度。

a.通過(guò)監(jiān)聽(tīng)圖片的 load 事件,當(dāng)事件觸發(fā)時(shí),表示圖片已經(jīng)加載完成,返回創(chuàng)建的div元素

b.在獲取數(shù)據(jù)loadNewData()函數(shù)中,對(duì)返回的數(shù)據(jù)執(zhí)行創(chuàng)建元素方法,并使用Promise.all()對(duì)由返回的div元素(Promise 實(shí)例)組成的Promise 數(shù)組進(jìn)行處理,當(dāng)每個(gè)Promise實(shí)例的狀態(tài)變?yōu)?fulfilled(所有圖片都加載完成),就執(zhí)行瀑布流布局

創(chuàng)建waterfall函數(shù),實(shí)現(xiàn)瀑布流

接收元素?cái)?shù)組,然后對(duì)每個(gè)元素進(jìn)行布局。如果元素在第一行,那么它的頂部位置就是 0,左側(cè)位置就是它的索引乘以(元素寬度 + 間隙)。如果元素不在第一行,那么我們首先找出高度最小的列,然后將元素放在這個(gè)列的下方,并更新這個(gè)列的高度。

function waterfall(items) {
  for (var i = loaded; i < items.length; i++) {
    let item = items[i]
    let height = item.offsetHeight
    if (i < columns) {
      //滿足這個(gè)條件則說(shuō)明在第一行
      item.style.top = 0
      item.style.left = (itemWidth + gap) * i + 'px'
      heightArr.push(height)
    } else {
      //其他行,先找出最小高度列的索引
      const minIndex = getMinIndex(heightArr)
      //top值就是最小列的高度+gap
      const top = heightArr[minIndex] + gap
      item.style.top = top + 'px'
      item.style.left = minIndex * (itemWidth + gap) + 'px'

      //修改原本最小列的高度 
      heightArr[minIndex] = top + height
    }
    loaded = items.length
  }
}

//用于獲取heightArr數(shù)組中值最小的列的索引。
const getMinIndex = (array) => {
  const min = Math.min.apply(null, array)
  return array.indexOf(min)
}

監(jiān)聽(tīng)頁(yè)面滾動(dòng),當(dāng)未顯示的元素內(nèi)容小于屏幕高度的一大半(這里設(shè)置的0.7,因?yàn)閿?shù)據(jù)加載比較慢,一般設(shè)置成0.5就可以),就需要加載新數(shù)據(jù)進(jìn)行展示

window.addEventListener('scroll', lazy)
function lazy() {
 const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
 const documentHeight = document.documentElement.scrollHeight
  // 未顯示的內(nèi)容 = 文檔(內(nèi)容)高度-滾動(dòng)高度-屏幕高度
  if (documentHeight - scrollTop - clientHeight < 0.7 * clientHeight) {
    loadNewData()
  }
}

小結(jié):

a. 簡(jiǎn)單封裝的請(qǐng)求數(shù)據(jù)方法getData()沒(méi)有展示出來(lái),請(qǐng)求的接口是從網(wǎng)上找的(地址),一次只能加載10張,并且加載很慢,可以自行查找接口。

b. 需要定義的變量

根據(jù)以上基本可以實(shí)現(xiàn)瀑布流了,排列順序和滾動(dòng)頁(yè)面加載數(shù)據(jù)也比較符合一般情況

以上就是js+CSS簡(jiǎn)單實(shí)現(xiàn)瀑布流布局的詳細(xì)內(nèi)容,更多關(guān)于js瀑布流布局的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 開(kāi)箱即用的開(kāi)源工具庫(kù)xijs示例詳解

    開(kāi)箱即用的開(kāi)源工具庫(kù)xijs示例詳解

    這篇文章主要為大家介紹了開(kāi)箱即用的開(kāi)源工具庫(kù)xijs示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 微信小程序中視頻的顯示與隱藏功能

    微信小程序中視頻的顯示與隱藏功能

    這篇文章主要介紹了微信小程序中視頻的顯示與隱藏,思路大概是定義一個(gè)標(biāo)記變量,控制視頻的播放與暫停,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-10-10
  • 微信小程序底部tabBar遮擋內(nèi)容的簡(jiǎn)單處理方法

    微信小程序底部tabBar遮擋內(nèi)容的簡(jiǎn)單處理方法

    幾乎每個(gè)app都會(huì)用到底部導(dǎo)航的,相對(duì)于小程序而言自然也是如此了,這篇文章主要給大家介紹了關(guān)于微信小程序底部tabBar遮擋內(nèi)容的簡(jiǎn)單處理方法,需要的朋友可以參考下
    2021-08-08
  • js編寫(xiě)trim()函數(shù)及正則表達(dá)式的運(yùn)用

    js編寫(xiě)trim()函數(shù)及正則表達(dá)式的運(yùn)用

    js中本身是沒(méi)有trim函數(shù)的,不過(guò)你可以自己寫(xiě)一個(gè),下面的實(shí)現(xiàn)方法是用到了正則表達(dá)式,效率不錯(cuò),并把這三個(gè)方法加入String對(duì)象的內(nèi)置方法中去
    2013-10-10
  • 小程序自定義索引菜單

    小程序自定義索引菜單

    這篇文章主要為大家詳細(xì)介紹了小程序自定義索引菜單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • 微信小程序?qū)崿F(xiàn)預(yù)約生成二維碼功能

    微信小程序?qū)崿F(xiàn)預(yù)約生成二維碼功能

    通過(guò)點(diǎn)擊預(yù)約按鈕即可生成二維碼憑碼入校參觀,下面小編通過(guò)實(shí)例代碼講解微信小程序?qū)崿F(xiàn)預(yù)約生成二維碼功能,感興趣的朋友跟隨小編一起看看吧
    2024-04-04
  • JavaScript中獲得CheckBox狀態(tài)的方法小結(jié)

    JavaScript中獲得CheckBox狀態(tài)的方法小結(jié)

    在 JavaScript 中,獲取復(fù)選框(CheckBox)的狀態(tài)(選中或未選中)可以通過(guò)以下幾種方式實(shí)現(xiàn),以下是具體方法及示例,并通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下
    2025-03-03
  • pnpm?monorepo?聯(lián)調(diào)方案問(wèn)題解析

    pnpm?monorepo?聯(lián)調(diào)方案問(wèn)題解析

    文章主要介紹了在pnpmmonorepo環(huán)境下進(jìn)行多庫(kù)聯(lián)調(diào)的方案,包括使用`pnpmlink`命令來(lái)鏈接指定的文件夾或全局的`node_modules`,并在項(xiàng)目中通過(guò)`pnpmlink--global<pkg>`來(lái)引用這些庫(kù),本文給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧
    2024-12-12
  • 值得分享和收藏的xmlplus組件學(xué)習(xí)教程

    值得分享和收藏的xmlplus組件學(xué)習(xí)教程

    值得分享和收藏的xmlplus組件學(xué)習(xí)教程,xmlplus是一個(gè)設(shè)計(jì)非常獨(dú)特 JavaScript 框架,用于快速開(kāi)發(fā)前后端項(xiàng)目,感興趣的小伙伴們可以參考一下
    2017-05-05
  • Bootstrap實(shí)現(xiàn)圓角、圓形頭像和響應(yīng)式圖片

    Bootstrap實(shí)現(xiàn)圓角、圓形頭像和響應(yīng)式圖片

    這篇文章主要介紹了Bootstrap實(shí)現(xiàn)圓角、圓形頭像和響應(yīng)式圖片的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12

最新評(píng)論

宣武区| 福建省| 井冈山市| 金山区| 小金县| 饶阳县| 乌兰县| 东乌珠穆沁旗| 长岭县| 金沙县| 青海省| 梅河口市| 三亚市| 比如县| 祁连县| 增城市| 天门市| 大宁县| 永清县| 防城港市| 平远县| 资溪县| 安庆市| 巴彦淖尔市| 宣汉县| 常山县| 华宁县| 南京市| 铜川市| 博爱县| 鲜城| 兴城市| 伊金霍洛旗| 宿松县| 邓州市| 昌都县| 东乡族自治县| 天门市| 荔浦县| 长垣县| 四会市|