vuejs實現瀑布流佈局(三)

前面寫過vuejs實現的瀑布流佈局,《vuejs實現瀑布流佈局(一)》和《vuejs實現瀑布流佈局(二)》也確實實現了瀑布流佈局,可是這個是基於SUI-Mobile實現的無限滾動。javascript

近日稍有空閒,回頭從新實現了一下移動端的瀑布流佈局,擺脫了移動端UI框架的束縛。css

移動端的適配,採用的是adaptive-version2.js,而無限加載採用的是Vue Scroller。html

最終實現的效果大體以下:vue

 

  解決了無限滾動和移動端適配的問題,瀑布流也就只剩下一個難點,怎麼樣讓高度不盡相同的圖片可以按左右順序排列下來,還不至於錯亂太多,相差太大。java

  事實上css也已經爲咱們提供瞭解決方案,可是css的方案有一個巨大的缺陷在於:一旦圖片發生變更,不論增長仍是減小,或者說圖片資源自己發生變化,他會將總體全部圖片的位置進行重排。就是說只要咱們動了任意一張圖片,其佈局可能會徹底不一樣。ios

  而js的瀑布流,主流方案彷佛只有兩種(具體更多的方案沒有研究),一個利用絕對定位,一個分左右兩欄(或者多欄),每欄內部垂直佈局,而依據圖片高度的不一樣,將其放入適合的欄目內,實現瀑布流。git

  咱們這裏採用的就是左右兩欄的佈局。github

<div class="waterfalls">
        <ul>
          <li class="photo" v-for="item in waterfallsLeft" :key="item.id + item.albumId+Math.random()">
            <a href="javascrip:;">
              <img :src="item.src" alt="">
            </a>
            <div class="desc-info">
              <p>編號:<span>{{item.albumId}}</span></p>
            </div>
            <div class="thumbnail">
              <div class="thumbnail-desc">
                <p>{{item.title}}</p>
                <span>{{item.thumbnailUrl}}</span>
              </div>
              <div class="praise active">
                <div>
                  <i>贊</i>
                  <span>{{item.albumId}}</span>
                </div>
              </div>
            </div>
          </li>
        </ul>
        <ul>
          <li class="photo" v-for="item in waterfallsRight" :key="item.id + item.albumId+Math.random()">
            <a href="javascrip:;">
              <img :src="item.src" alt="">
            </a>
            <div class="desc-info">
              <p>編號:<span>00001</span></p>
            </div>
            <div class="thumbnail">
              <div class="thumbnail-desc">
                <p>雙語小學</p>
                <span>詹天佑</span>
              </div>
              <div class="praise active">
                <div>
                  <i>贊</i>
                  <span>92</span>
                </div>
              </div>
            </div>
          </li>
        </ul>
      </div>

  div.waterfalls做爲外層包裹,而裏面的兩個ul,就是兩欄,li就是每一張圖片所對應的數據。ul寬度各佔50%,而後浮動。剩下的就是怎麼樣讓個張圖片自動歸位,進入waterfallsLeft和waterfallsRight。json

  首先請求數據:axios

  

getData(done){
      let _this = this;
      axios.get("https://jsonplaceholder.typicode.com/photos", {page: this.page})
          .then(res=>res.data)
          .then(res => {
            let counts = res.slice((this.page-1) * this.pageCount, this.page * this.pageCount)
            //  console.log(counts.length)
            counts.forEach(item => {
              item.src ='http://cued.xunlei.com/demos/publ/img/P_'+ this.randomNum()+ '.jpg'
            });
            this.page++;
            this.itemsLen = counts.length;
            this.judgeAllLoaded(counts)
            self.bottom = self.bottom + 10;
            if(done) done();
          })
    },
    randomNum(){  // 三位數隨機數,162之內
      let random = Math.floor(Math.random() * 162)
      return random = random < 10 ? '00'+random : random < 100 ? '0'+random : ''+random;
    },

  請求的是https://jsonplaceholder.typicode.com/photos,有不少數據能夠進行一些模擬請求,可是其返回的圖片都是相同大小的,因此爲其添加圖片資源,item.src ='http://cued.xunlei.com/demos/publ/img/P_'+ this.randomNum()+ '.jpg'。

  有了數據,就得按照圖片在相同寬度的狀況下,高度不一樣,將其分組分別進入左右兩欄this.judgeAllLoaded(counts)。 

judgeAllLoaded(items){   // 判斷全部圖片是否加載完成
      let _this = this;
      items.forEach(item => {
        let IMG = new Image();
        IMG.src = item.src;
        IMG.width = 100;
        IMG.onload = function () {  
          _this.flag++;
          if(_this.leftHeight <= _this.rightHeight){
            _this.leftHeight += IMG.height;
            _this.waterfallsLeft.push(item)
          }else{
            _this.rightHeight += IMG.height;
            _this.waterfallsRight.push(item)
          }
        }
      })
    }

  這裏關鍵點在於:IMG.src = item.src; IMG.width = 100; IMG.onload = function;

  爲IMG對象添加src,並設置相同寬度100,而後等待圖片加載完成onload,在圖片加載完成以後,判斷左右兩欄,哪一欄高度較低,該條數據進入哪一欄,這裏有一個不大不小的問題,就是因爲不肯定哪張圖片先加載完成,致使即便請求回來的數據相同,其排列的位置也未必相同,可是已經留下了解決flag做爲可能的解決方案。就是每加載完成一張圖片,flag自增,監聽flag的變化,當flag的值與請求回來的數據相等時,再進行數據分配,理論上應該能夠解決該問題,留待後面實現。

  數據分配完成,其實瀑布流也已經實現了,剩下的就是無限滾動,繼續分配請求回來的數據了。

  具體代碼能夠查看GitHub上的GitProjectWaterfalls

相關文章
相關標籤/搜索