原生js實現瀑布流及微信小程序中使用左右兩列實現瀑布流

使用css實現瀑布流並不實用,由於css實現的瀑布流都是以列來排列的,這裏記錄下用js實現瀑布流,以及微信小程序中使用左右兩列來實現瀑布流

1.效果圖

clipboard.png

2.原生js實現瀑布流

  • html文件
<div id="root">
    <div class="item">
        <div class="itemImg">
            <img src="../images/1.jpeg" alt="" />
        </div>
    </div>
    <div class="item">
        <div class="itemImg">
            <img src="../images/3.jpeg" alt="" />
        </div>
    </div>
    <div class="item">
        <div class="itemImg">
            <img src="../images/2.jpg" alt="" />
        </div>
    </div>
</div>
  • 圖片能夠本身找點替換下就能夠了
  • css文件
*{
    margin: 0;
    padding: 0;
}
#root{
    position: relative;
}
.item{
    float: left;
    padding: 5px;
}
/* 添加陰影的時候,加上border會顯得更加有點懸浮感 */
.itemImg{
    padding: 5px;
    border: 1px solid #ccc;
    box-shadow: 0 0 5px #ccc;
    border-radius: 5px;
}
.itemImg img{
    width: 230px;
    height: auto;
}
  • js文件
window.onload = function () {

    /* 計算圖片列數及獲取最小高度圖片 */
    generateImg('root', 'item');

    /* 對窗口大小改變進行監聽,大小改變則從新佈局 */
    window.addEventListener('resize', function() {
        generateImg('root', 'item')
    });

    /* 圖片對象 */
    let imgData = {
        images: [
            {
                "src":"23.png"
            },
            {
                "src":"22.png"
            },
            {
                "src":"2.jpg"
            },
            {
                "src":"4.jpg"
            },
            {
                "src":"7.jpg"
            }
        ]
    };
    /* 對滾動監聽 */
    window.addEventListener('scroll', function() {
        if(checkIsScroll()) {
            let rootElement = document.getElementById('root');
            /* 利用documentFragment來建立 */
//                    let documentFragment = document.createDocumentFragment();
            let length = imgData.images.length;

            /* 循環建立圖片組 */
            for(let i = 0; i < length; i++) {
                let itemElement = document.createElement('div');
                itemElement.className = 'item';
                rootElement.appendChild(itemElement);
                let itemImgElement = document.createElement('div');
                itemImgElement.className = 'itemImg';
                itemElement.appendChild(itemImgElement);
                let itemImg = document.createElement('img');
                itemImg.style.cssText = 'opacity: 0; transform:scale(0)';
                itemImg.src = "../images/" + imgData.images[i].src;
                itemImgElement.appendChild(itemImg);
//                        documentFragment.appendChild(itemElement);

                /* 在1秒後讓圖片顯示出來 */
                (function(img){
                    setTimeout(function(){
                        img.style.cssText="opacity:1;transform:scale(1)";
                    },1000);
                })(itemImg);
            }
//                    rootElement.appendChild(documentFragment);
            generateImg('root', 'item');
        }
    });
};

/* 計算圖片列數及獲取最小高度圖片 */
function generateImg(parent, content) {
    /* 獲取父元素及其因此節點內容 */
    let parentElement = document.getElementById(parent);
    let childContent = getChildElement(parentElement, content);

    /* 獲取圖片寬度 */
    let imgWidth = childContent[0].offsetWidth;
    /* 獲取一行圖片造成的列數 */
    let imgColumn = Math.floor(document.documentElement.clientWidth / imgWidth);
    /* 從新設置父級容器的寬度 */
    parentElement.style.cssText = 'width:' + imgColumn * imgWidth + 'px;margin:0 auto';

    /* 存儲每一個圖片的高度,以此來找到最小圖片高 */
    let imgHeightArray = [];
    let length = childContent.length;
    for(let i = 0; i < length; i++) {
        /* i<imgColumn統計每一行的圖片高度 */
        if(i < imgColumn) {
            /* 防止用戶改變窗口大小時,內容樣式錯亂 */
            childContent[i].style.cssText = '';
            imgHeightArray.push(childContent[i].offsetHeight);
        } else {
            /* 若是不是這一行的,則找到最小值和最小值的索引值 */
            let minHeight = getMinImgHeight(imgHeightArray);
            let minHeightIndex = getMinHeightIndex(imgHeightArray, minHeight);
            /* 對這個圖片設置位置 */
            childContent[i].style.position = 'absolute';
            childContent[i].style.top = minHeight + 'px';
            childContent[i].style.left = childContent[minHeightIndex].offsetLeft + 'px';
            /* 更換此時的最小高度 */
            imgHeightArray[minHeightIndex] = childContent[i].offsetHeight + minHeight;
        }
    }
}

/* 檢測滾動是否達到了可視區 */
function checkIsScroll() {
    /* 獲取root根節點 */
    let parentElement = document.getElementById('root');
    /* 獲取父元素下的類名爲box的元素節點 */
    let childContent = getChildElement(parentElement, 'item');

    /* 獲取最後一個元素的高度 */
    let lastElementHeight = childContent[childContent.length - 1].offsetTop;
    /* 獲取滾動的距離 */
    let scrollTopSpace = document.documentElement.scrollTop || document.body.scrollTop;
    /* 獲取可視區的距離 */
    let clientHeight = document.documentElement.clientHeight || document.body.clientHeight;

    if(lastElementHeight > scrollTopSpace + clientHeight) {
        return true;
    }
}
/* 獲取子節點的全部內容 */
function getChildElement(parentElement, content) {
    /* 存儲元素信息 */
    let elementArray = [];
    /* 獲取父元素下的全部節點信息 */
    let allElement = parentElement.getElementsByTagName('*');
    let length = allElement.length;
    for (let i = 0; i < length; i++) {
        /* 找到對應的類名 */
        if (allElement[i].className === content) {
            elementArray.push(allElement[i]);
        }
    }
    return elementArray;
}

/* 獲取圖片最小高度 */
function getMinImgHeight(heightArray) {
    let length = heightArray.length;
    let minHeight = heightArray[0];
    for(let i = 0; i < length; i++) {
        minHeight = Math.min(minHeight, heightArray[i]);
    }
    return minHeight;
}

/* 獲取圖片最小高度的索引值 */
function getMinHeightIndex(heightArray, minHeight) {
    let length = heightArray.length;
    for(let i = 0; i < length; i++) {
        if(heightArray[i] == minHeight) {
            return i;
        }
    }
}

3.微信小程序中實現瀑布流

  • 效果圖
clipboard.png
  • wxml文件
<view class="cateCommodity">
  <view class="leftContainer">
    <block wx:for="{{imageArray}}" wx:key="{{item.id}}">
      <view class="cateItem" wx:if="{{index%2==0}}">
        <view class="item">
          <image src="{{item.src}}" class="itemImg" mode="widthFix"></image>
          <view class="title">{{item.title}}</view>
        </view>
      </view>
    </block>
  </view>
  <view class="rightContainer">
    <block wx:for="{{imageArray}}" wx:key="{{item.id}}">
      <view class="cateItem" wx:if="{{index%2==1}}">
        <view class="item">
          <image src="{{item.src}}" class="itemImg" mode="widthFix"></image>
          <view class="title">{{item.title}}</view>
        </view>
      </view>
    </block>
  </view>
</view>
<view class="skipTop" catchtap="skipTop" wx:if="{{showTopImage}}">
  <image src="http://boweisou.oss-cn-shenzhen.aliyuncs.com/images/0/2018/11/ZBtqujbbcGjBDgjt0bbJqbTuGqq0z8.png"></image>
</view>
  • wxss文件
page{
  background: #f6f6f6;
}
/* 最外層 */
.cateCommodity {
  display: flex;
  padding: 20rpx 28rpx 8rpx;
  box-sizing: border-box;
  font-size: 28rpx;
}
/* 左右兩個容器 */
.leftContainer{
  display: flex;
  margin-right: 22rpx;
  flex-direction: column;
}
.rightContainer{
  display: flex;
  flex-direction: column;
}
/* 圖片容器 */
.cateItem {
  margin-bottom: 20rpx;
}
.item{
  padding: 20rpx 22rpx;
  width: 335rpx;
  box-sizing: border-box;
  background: #fff;
  border-radius: 6rpx;
}
.itemImg{
  margin-bottom: 14rpx;
  width: 100%;
  vertical-align: middle;
  border-radius: 6rpx;
}
.title{
  display: -webkit-box;
  overflow: hidden;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  line-height: 1.5;
}
/* 返回頂部 */
.skipTop {
  position: fixed;
  bottom: 30rpx;
  right: 20rpx;
  width: 90rpx;
  height: 90rpx;
}

.skipTop image {
  width: 100%;
  height: 100%;
  vertical-align: middle;
}
  • js文件
Page({
  data: {
    imageArray: [
      {
        id: 1,
        src: '../../images/avatar.jpeg',
        title: '現代新中式創意陶瓷簡約擺件客廳家居玄關軟裝飾品家居酒櫃盤子'
      },
      {
        id: 1,
        src: '../../images/avatar3.jpg',
        title: '秋冬季新款2018休閒運動服套裝女士韓版金絲絨衛衣加絨加厚兩件套'
      },
      {
        id: 1,
        src: '../../images/avatar4.jpeg',
        title: '女童牀上用品四件套公主房1.2m牀品純棉女孩1.8兒童牀單三件套1.5'
      },
      {
        id: 1,
        src: '../../images/avatar7.jpg',
        title: '嬰兒牀圓牀蚊賬落地款寶寶橢圓牀蚊賬支架款兒童牀蚊賬BB牀小蚊賬'
      },
      {
        id: 1,
        src: '../../images/avatar9.jpeg',
        title: '包郵動感158T速滑鞋輪滑鞋競速鞋高端碳纖鞋 固定碼 專業定製'
      },
      {
        id: 1,
        src: '../../images/logo7.jpg',
        title: 'Infanton落地嬰兒牀蚊賬帶支架兒童牀蚊賬寶寶蚊賬嬰童蚊賬'
      },
      {
        id: 1,
        src: '../../images/logo6.jpg',
        title: '老A輪滑 米高seba hl碳纖版SEBA HL CARBON 平花鞋剎車鞋全能鞋'
      },
      {
        id: 1,
        src: '../../images/logo.jpeg',
        title: '洋洋法代 sandro 17秋冬 一粒扣羊毛長款大衣外套EKIN M9575H'
      },
    ],
    showTopImage: false,
  },
  onPageScroll(event) {
    /* 利用兩個條件,防止重複的進行setData操做 */
    if (event.scrollTop > 300 && this.data.showTopImage == false) {
      this.setData({
        showTopImage: true
      })
    } else if (event.scrollTop < 300 && this.data.showTopImage == true) {
      this.setData({
        showTopImage: false
      })
    }
  },
  skipTop() {
    /* 返回頂部 */
    wx.pageScrollTo({
      scrollTop: 0,
      duration: 300
    });
    this.setData({
      showTopImage: false
    });
  },
  onReachBottom: function () {
    let temporaryArray = this.data.imageArray;
    temporaryArray.push(...this.data.imageArray);
    this.setData({
      imageArray: temporaryArray
    })
  },
})
  • 左右兩列實現瀑布流其實就是對同一數組進行了兩次渲染,只是把其中的一半給隱藏了
正在努力學習中,若對你的學習有幫助,留下你的印記唄(點個贊咯^_^)
相關文章
相關標籤/搜索