国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

小程序之圖片瀑布流(最全實(shí)現(xiàn)方式,額外加送懶加載)

rubyshen / 1992人閱讀

摘要:完整代碼請(qǐng)戳我們回到小程序,此時(shí)接口返回的數(shù)據(jù)如下可以看到每個(gè)圖片都有高度了,接下來我們實(shí)現(xiàn)瀑布流布局,等下,我們搞下瀑布流布局的懶加載,關(guān)于小程序的懶加載,猛戳了解更多。

效果圖

來來來,看啊看,外面的世界多好看,

效果圖展示的是瀑布流布局 && 懶加載的效果

數(shù)據(jù)

圖片數(shù)據(jù)來源張鑫旭的網(wǎng)絡(luò)日志

先說下我們的圖片鏈接格式

所有的鏈接都是http://cued.xunlei.com/demos/publ/img/P_${name}.jpg這樣的格式,我們需要改變name的值就行了,當(dāng)name值小于10的時(shí)候,格式是00x,如002003,大于10的時(shí)候就是023這種。

定義

瀑布流布局是一種比較流行的頁面布局方式, 最早采用此布局的網(wǎng)站是Pinterest, 圖片寬度是固定的,高度自動(dòng),產(chǎn)生一種參差不齊的美感。

原理

原理很簡單,主要分為以下幾步

1、定義高度數(shù)組和列數(shù)

2、遍歷元素,個(gè)數(shù)小于列數(shù)的直接push到數(shù)組中

3、大于列數(shù)的,獲取高度數(shù)組中最小的值,定義元素的top和left值

4、重要一點(diǎn) 更新高度數(shù)組,將最小高度加上當(dāng)前元素的高度

知道原理了,代碼應(yīng)該怎么寫呢?這里用web端來示例,大概如下

let heightArr = []
let col = 2
let allBox = document.querySelectorAll(".box") // 獲取所有盒子

for(let i in allBox){
    
    let boxWidth = allBox[0].offsetWidth  // 獲取盒子寬度 都一樣直接取第一個(gè)
  let boxHeight = allBox[i].offsetHeight
    if(i < col){    
        heightArr.push(boxHeight)  // 把第一行高度都添加進(jìn)去
    } else {  // 進(jìn)行布局操作
        
        let minHeight = Mac.min.apply(null, heightArr)  // 獲取最小高度
        let minIndex = getIndex(heightArr, minHeight)  // 獲取最小高度的下標(biāo) 要不就是0 要不就是1
        allBox[i].style.position = "absolute"
        allBox[i].style.top = minHeight + "px"
        allBox[i].style.width = minIndex * boxWidth + "px"
        
        heightArr[minIndex] += boxHeight // 更新最新高度 
    }
}

// 獲取下標(biāo)
getIndex(arr, val){
    for(i in arr){
        if(arr[i] == val) {
            return i
        }
    }
}

上面就是實(shí)現(xiàn)瀑布流的主要邏輯,這里大概寫了下,接下來我們看看小程序怎么實(shí)現(xiàn)。

實(shí)現(xiàn)

在web頁面里面我們可以直接獲取、操作DOM,實(shí)現(xiàn)起來很方便,何況還有很多的jquery插件可以使用。我們知道小程序里面是沒有DOM的,那應(yīng)該怎么實(shí)現(xiàn)呢?我們把思路轉(zhuǎn)換下就行了。

這里我們用三種方式來實(shí)現(xiàn)瀑布流布局。

CSS

使用css3來實(shí)現(xiàn)是最簡單的,我們先撿簡單的來說,

使用column-count屬性設(shè)置列數(shù)

使用wx-if進(jìn)行判斷將圖片渲染到左側(cè)還是右側(cè)

wxml

    
      
 
wxss
.container{
  column-count: 2;  /*設(shè)置列數(shù)*/ 
  column-gap:2rpx;
  padding-left: 8rpx;
}
image{
  width: 182px;
  box-shadow: 2px 2px 4px rgba(0,0,0,.4);
}

js獲取下數(shù)據(jù)即可,這里就不贅述了。

節(jié)點(diǎn)信息

小程序可以通過WXML節(jié)點(diǎn)信息API來獲取元素的信息,接下來我們來擼碼。

wxml

      
             
      
 
wxss
.container{
  position: relative;
  display: flow-root;
}
.box{
  float: left;
  display: flex;
  margin-left:5rpx;
  box-shadow: 2rpx 2rpx 5rpx rgba(0,0,0,.3);
  border: 1rpx solid #ccc;
  box-sizing: border-box;
  padding: 10px;
}
.box:nth-child(2){
  margin-left: 12rpx;
}
image{
  width: 100%;
}
js

圖片鏈接為http://cued.xunlei.com/demos/publ/img/P_${name}.jpg, 只需要更改name就行了

首先處理我們的數(shù)據(jù)

// 創(chuàng)建長度為30的數(shù)組
const mockData = () => {
  return Array.from(Array(30).keys()).map(item => {
    if (item < 10) {
      return "00" + item
    } else {
      return "0" + item
    }
  })

}
// 擴(kuò)展成我們需要的數(shù)據(jù)
const createGroup = () => {
  let group = []
  let list = mockData()
  list.forEach(item => {
    group.push({ name: item, position: "static", top: "", left: "" })
  })
  return group
}

然后進(jìn)行瀑布流布局,主要代碼如下

load(e){  // 監(jiān)聽圖片加載完 獲取圖片的高度
    this.setData({
      height: [...this.data.height, e.detail.height]
    })
    this.showImg()  // 調(diào)用渲染函數(shù)
},

showImg(){
    let height = this.data.height
    if (height.lenth != this.data.group .legth){  // 保證所有圖片加載完
      return
    }
    setTimeout(()=>{ // 異步執(zhí)行
      wx.createSelectorQuery().selectAll(".box").boundingClientRect((ret) => {
        let cols = 2
        var group = this.data.group
        var heightArr = [];
        for (var i = 0; i < ret.length; i++) {
          var boxHeight = height[i]
          if (i < cols) {
            heightArr.push(boxHeight + 25)
          } else {
            var minBoxHeight = Math.min.apply(null, heightArr);
            var minBoxIndex = getMinBoxIndex(minBoxHeight, heightArr);
            group[i].position = "absolute"
            group[i].top = `${minBoxHeight}px`
            group[i].left = minBoxIndex * this.data.width / 2 + "px"
            group[i].left = minBoxIndex == 0 ?  minBoxIndex * this.data.width / 2 + "px" : minBoxIndex * this.data.width / 2 + 5 + "px"
            heightArr[minBoxIndex] += (boxHeight + 25)
          }
        }

        this.setData({
          group
        })
        wx.hideLoading()

      }).exec()
    }, 200)
    
  }

可以看到實(shí)現(xiàn)的邏輯和上面的大概類似,只不過這里我們修改的是數(shù)據(jù),畢竟小程序是數(shù)據(jù)驅(qū)動(dòng)的嘛。

這里主要我們監(jiān)聽image組件的bindload事件來獲取每張圖片的高度,獲取了高度才能進(jìn)行布局,大部分的時(shí)間也都用來加載圖片了,能不能優(yōu)化呢?當(dāng)然可以了,我們使用node把數(shù)據(jù)包裝下。

后端處理數(shù)據(jù)

上面我們說到在小程序內(nèi)部獲取圖片的高度是個(gè)費(fèi)力不討好的事,我們使用node來獲取圖片高度,然后包裝下再給小程序使用。

使用request進(jìn)行請(qǐng)求

使用image-size獲取圖片的高度

最后將獲取后將數(shù)據(jù)寫入文件,啟動(dòng)一個(gè)服務(wù)提供接口

這里主要說下碰到的問題

1、request模塊的請(qǐng)求默認(rèn)返回來的是個(gè)String類型的字符串,使用image-size模塊傳入的必須是Buffer,怎么破呢?在request請(qǐng)求中設(shè)置encodingnull即可

2、我們這里爬取了100張圖片,怎么保證都已經(jīng)爬取完了呢?可以這樣寫

Promise.all(List.map(item => getImgData(item)))  // getImgData函數(shù)是獲取圖片的函數(shù) 會(huì)返回個(gè)promise

3、如果請(qǐng)求了幾次,發(fā)現(xiàn)有的圖片獲取不到了,報(bào)錯(cuò)了,怎么回事呢,人家畢竟做了防爬的,恭喜你中獎(jiǎng)了,換個(gè)ip再試吧(可以把代碼放在服務(wù)器上面,或者換個(gè)Wi-Fi),其實(shí)我們只需要爬一次就行,生成完文件還爬干嘛啊。

完整代碼請(qǐng)戳github

我們回到小程序,此時(shí)接口返回的數(shù)據(jù)如下

可以看到每個(gè)圖片都有高度了,接下來我們實(shí)現(xiàn)瀑布流布局,等下,我們搞下瀑布流布局的懶加載,關(guān)于小程序的懶加載,猛戳了解更多。

怎么實(shí)現(xiàn)呢?主要分為兩步

1、將元素瀑布流布局

2、創(chuàng)建IntersectionObserver,進(jìn)行懶加載

先開始我們的布局吧

wxml

  
    
    
  

上面我們使用wx-if通過show這個(gè)字段來進(jìn)行判斷了圖片是否加載,

使用一個(gè)view組件用來占位,然后更改show字段就可以顯示圖片了

js

我們使用兩個(gè)for循環(huán),先來進(jìn)行布局

let cols = 2
    let list = this.data.list
    let heightArr = [];


    for(let i in list){
      var boxHeight = list[i].height
      if (i < cols) {
        heightArr.push(boxHeight + 5)
      } else {
        var minBoxHeight = Math.min.apply(null, heightArr);
        var minBoxIndex = getMinBoxIndex(minBoxHeight, heightArr);
        list[i].position = "absolute"
        list[i].top = `${minBoxHeight}px`
        list[i].left = minBoxIndex * 182 + "px"
        list[i].left = minBoxIndex == 0 ? minBoxIndex * 182 + "px" : minBoxIndex * 182 + 4 + "px"
        heightArr[minBoxIndex] += (boxHeight + 5)
      }
    }
    this.setData({
      list
    })

布局完后,創(chuàng)建IntersectionObserver,動(dòng)態(tài)判斷image節(jié)點(diǎn)的顯示

for (let i in list) {
      
    wx.createIntersectionObserver().relativeToViewport({ bottom: 20 }).observe(".pic-" + i, (ret) => {
        if (ret.intersectionRatio > 0) {
          list[i].show = true
        }
        this.setData({
          list
        })
 })
}
最后

我們使用三種方式完成了小程序的瀑布流布局,還額外完成了基于瀑布流的懶加載。可以發(fā)現(xiàn)使用css最簡便,雖然小程序不能操作DOM,但是我們改完數(shù)據(jù)其實(shí)和改變DOM一樣,將觀念轉(zhuǎn)變過來,小程序的開發(fā)還是很爽的。

最后的最后,各位,周末快樂。

github

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/95026.html

相關(guān)文章

  • 原生 JS 實(shí)現(xiàn)一個(gè)瀑布插件

    摘要:瀑布流布局中的圖片有一個(gè)核心特點(diǎn)等寬不定等高,瀑布流布局在國內(nèi)網(wǎng)網(wǎng)站都有一定規(guī)模的使用,比如花瓣網(wǎng)等等。那么接下來就基于這個(gè)特點(diǎn)開始瀑布流探索之旅。 showImg(https://segmentfault.com/img/remote/1460000013059759?w=640&h=280); 瀑布流布局中的圖片有一個(gè)核心特點(diǎn) —— 等寬不定等高,瀑布流布局在國內(nèi)網(wǎng)網(wǎng)站都有一定規(guī)模...

    Alfred 評(píng)論0 收藏0
  • 原生 JS 實(shí)現(xiàn)一個(gè)瀑布插件

    摘要:瀑布流布局中的圖片有一個(gè)核心特點(diǎn)等寬不定等高,瀑布流布局在國內(nèi)網(wǎng)網(wǎng)站都有一定規(guī)模的使用,比如花瓣網(wǎng)等等。那么接下來就基于這個(gè)特點(diǎn)開始瀑布流探索之旅。 showImg(https://segmentfault.com/img/remote/1460000013059759?w=640&h=280); 瀑布流布局中的圖片有一個(gè)核心特點(diǎn) —— 等寬不定等高,瀑布流布局在國內(nèi)網(wǎng)網(wǎng)站都有一定規(guī)模...

    lavnFan 評(píng)論0 收藏0
  • 原生 JS 實(shí)現(xiàn)一個(gè)瀑布插件

    摘要:瀑布流布局中的圖片有一個(gè)核心特點(diǎn)等寬不定等高,瀑布流布局在國內(nèi)網(wǎng)網(wǎng)站都有一定規(guī)模的使用,比如花瓣網(wǎng)等等。那么接下來就基于這個(gè)特點(diǎn)開始瀑布流探索之旅。 showImg(https://segmentfault.com/img/remote/1460000013059759?w=640&h=280); 瀑布流布局中的圖片有一個(gè)核心特點(diǎn) —— 等寬不定等高,瀑布流布局在國內(nèi)網(wǎng)網(wǎng)站都有一定規(guī)模...

    wenyiweb 評(píng)論0 收藏0
  • 程序瀑布效果,解決左右兩邊高度差距過大的問題

    摘要:參考小紅書的瀑布流效果,小紅書是分左右兩欄的,按照奇數(shù)偶數(shù)來顯示就可以。但是問題來了,隨著每個(gè)元素高度的不確定性,很大幾率會(huì)出現(xiàn)左右兩欄高度相差大的問題。 想要實(shí)現(xiàn)瀑布流的布局效果,并且是按照從左到右順序顯示的話,css布局方式暫時(shí)還不能滿足我們的需求。參考小紅書的瀑布流效果,小紅書是分左右兩欄的,按照奇數(shù)偶數(shù)來顯示就可以。 ...

    CoffeX 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<