原生JavaScript与jQuery实现瀑布流布局详解

作者:纸飞机时间:2026-10-21 23:50:09浏览:469

本文详细解析如何使用原生JavaScript和jQuery实现网页瀑布流布局。核心逻辑包括获取容器元素、计算列数并设置页面宽度、动态定位图片至高度最小列,以及通过滚动事件触发懒加载机制。文章提供了完整的代码实现思路与关键函数解析,帮助开发者掌握动态内容排列与无限滚动加载技术。

瀑布流布局概述

概述

本文记录了在慕课网学习使用原生JavaScript和jQuery实现瀑布流效果的笔记。

原生JavaScript实现

原生JavaScript实现方案

HTML基本结构如下:


<div id="main">
 <div class="box">
  <div class="pic"><img src="images/1.jpg" alt=""></div>
 </div>
 <div class="box">
  <div class="pic"><img src="images/2.jpg" alt=""></div>
 </div>
  ...
  ...
  ...
 </div>

CSS基本样式定义如下:


*{
 margin: 0px;
 padding: 0px;
 }
 #main{
 position: relative;
 }
 .box{
 padding: 15px 0 0 15px;
 float: left;
 }
 .pic{
 padding: 10px;
 border: 1px solid #ccc;
 border-radius: 5px;
 box-shadow: 0 0 5px #ccc;
 }

实现逻辑思路:

第一步,获取ID为#main容器下的所有class为.box的元素。

第二步,计算页面中图片显示的列数,并据此设置页面的总宽度。

第三步,找出当前所有列中高度最小的那一列。

第四步,从第二行开始,将新图片设置为相对定位,并将其放置在高度最小列的下方。

第五步,更新该列的高度数据,并重复执行步骤3和4,直到所有图片加载完毕。

第六步,根据最后一张图片的位置判断是否需要继续加载图片(即实现懒加载功能)。

具体代码实现步骤:

1. 获取#main下的所有.box元素。


  //将main下的所有class为box的元素取出来
  var oParent = document.getElementById(parent);
  var oBox = getByClass(oParent,box);

// 根据class获取元素
 function getByClass(parent,clsname){
  var arr = [];//用来存储获取到的所有class为box的元素
  var oElement = parent.getElementsByTagName('*');
  for(var i=0;i<oElement.length;i++){
  if(oElement[i].className == clsname){
   arr.push(oElement[i]);
  }
  }
  return arr;
 }

2. 计算页面中图片有几列,并设置页面的宽度。


  //计算整个页面显示的列数(页面宽/box的宽)
  var oBoxW = oBox[0].offsetWidth;
  var cols = Math.floor(document.documentElement.clientWidth/oBoxW);
  //设置main的宽
  oParent.style.cssText = 'width:' + oBoxW*cols + 'px;margin:0 auto;'; 

3. 找出这几列中高度最小的列。

4. 从第二行开始,设置图片为相对定位,把一张图片放到高度最小列的下面。

5. 更新列的高度,重复3、4、5步骤,直至图片加载完。


//存储每列的高度
  var hArr = [];
  for(var i=0;i<oBox.length;i++){
  if(i<cols){
   //第一行图片的高度
   hArr.push(oBox[i].offsetHeight);
  }else{
   var minH = Math.min.apply(null,hArr);
   var index = getMinIndex(hArr,minH);
   oBox[i].style.position = "absolute";
   oBox[i].style.top = minH + 'px';
   //oBox[i].style.left = oBoxW*index+'px';
   oBox[i].style.left = oBox[index].offsetLeft + 'px';
   //更新每列的高度
   hArr[index] += oBox[i].offsetHeight;
  }
  }

//获取每列高度最小的索引值
 function getMinIndex(arr,value){
  for(var i in arr){
  if(arr[i] == value){
   return i;
  }
  }
 }

6. 根据最后一张图片的位置确定是否继续加载图片(懒加载)。

假设后台返回的数据格式如下:


  //数据
  var dataInt = {'data':[{'src':'1.jpg'},{'src':'2.jpg'},{'src':'3.jpg'},{'src':'4.jpg'}]};  

监听滚动条滚动事件以执行加载逻辑。


  //滚动条滚动时
  window.onscroll = function(){
  scrollSlide(dataInt);
  }  

通过判断最后一张图片的位置,来决定是否进行数据加载。


//判断是否具有了滚条加载数据块的条件
 function checkScrollSlide(parent,clsname){
  var oParent = document.getElementById(parent);
  var oBox = getByClass(oParent,clsname);
  var lastBoxH = oBox[oBox.length-1].offsetTop + Math.floor(oBox[oBox.length-1].offsetHeight/2);
  var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  var height = document.documentElement.clientHeight || document.body.clientHeight;
  return (lastBoxH < scrollTop + height)? true:false;
 }

执行图片加载操作。


//滚动条滚动时执行
 function scrollSlide(dataInt){
  ////判断是否具有了滚条加载数据块的条件
  if(checkScrollSlide('main','box')){
  var oParent = document.getElementById('main');
  //将数据块渲染到当前页面的尾部
  for(var i=0;i<dataInt.data.length;i++){
   var oBoxs = document.createElement('div');
   oBoxs.className = 'box';
   oParent.appendChild(oBoxs);
   var oPic = document.createElement('div');
   oPic.className = 'pic';
   oBoxs.appendChild(oPic);
   var oImg = document.createElement('img');
   oImg.src = 'images/' + dataInt.data[i].src;
   oPic.appendChild(oImg);
  }
  waterfall('main','box');
  }

jQuery实现方案

jQuery实现方案

使用jQuery实现的思路与原生JavaScript一致,此处直接展示相关代码。


$(window).on('load',function(){
  waterfall();
  var dataInt={'data':[{'src':'1.jpg'},{'src':'2.jpg'},{'src':'3.jpg'},{'src':'4.jpg'}]};
  $(window).on('scroll',function(){
  scrollSlide(dataInt);
  })
 });
 function waterfall(){
  var $oBox = $('#main>div');
  var oBoxW = $oBox.eq(0).outerWidth();
  var cols = Math.floor($(window).width()/oBoxW);
  $('#main').css({
  'width' : cols * oBoxW,
  'margin' : '0 auto'
  });
  var hArr = [];
  $oBox.each(function(index,value){
  var oBoxH = $oBox.eq(index).height();
  if(index<cols){
   hArr.push(oBoxH);
  }else{
   var minH = Math.min.apply(null,hArr);
   var minHIndex = $.inArray(minH,hArr);
   $(value).css({
   'position' : 'absolute',
   'top': minH + 15,
   'left' : $oBox.eq( minHIndex ).position().left
   });
   hArr[minHIndex] += $oBox.eq(index).height() + 15;
  }
  });
 }
 function checkScrollSlide(){
  var $lastBox = $('#main>div').last();
  var lastBoxH = $lastBox.offset().top + Math.floor($lastBox.height()/2);
  var scrollTop = $(window).scrollTop();
  var clientH = $(window).height();
  return (lastBoxH < scrollTop + clientH) ? true : false;
 }
 function scrollSlide(dataInt){
  if(checkScrollSlide()){
  $.each(dataInt.data,function(index,value){
   var $Box = $('<div>').addClass('box').appendTo('#main');
   var $Pic = $('<div>').addClass('pic').appendTo($Box);
   $('<img>').attr('src','images/' + $(value).attr('src')).appendTo($Pic);
  })
  waterfall();
  }
 }

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持本站!

作者最新文章