Home Web Front-end JS Tutorial jquery implements simple waterfall flow layout

jquery implements simple waterfall flow layout

Dec 28, 2016 am 10:10 AM

is the principle that will be mentioned at the beginning

There are two types of waterfall flow layouts, one is fixed columns and the other is non-fixed columns. This article mainly describes the implementation of the first type.

The characteristic of fixed columns is: no matter how the page is scaled, the total number of columns in each row is the same.

From a layout perspective, a waterfall flow with one row and four columns is four li tags. Through certain events (such as how many px the scroll bar scrolls), then read it, and then dynamically add the data to the page.

The principle of adding data is not to add based on the li index value, but to add dynamically based on the column with the shortest height among the columns. Otherwise, the page may be ugly (the left and right heights are not uniform).

The example involves the ajax method. Can be run in a server environment.

stop bullshitting. Apply the style directly.

<ul id="ul1">
 <li>
  <div>
   <img  src="/static/imghw/default1.png"  data-src="images/1.jpg"  class="lazy"   alt="jquery implements simple waterfall flow layout" >
   <p>我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述</p>
  </div>
 </li>
 <li>
  <div>
   <img  src="/static/imghw/default1.png"  data-src="images/2.jpg"  class="lazy"   alt="jquery implements simple waterfall flow layout" >
   <p>我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述</p>
  </div>
 </li>
 <li>
  <div>
   <img  src="/static/imghw/default1.png"  data-src="images/3.jpg"  class="lazy"   alt="jquery implements simple waterfall flow layout" >
   <p>我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述</p>
  </div>
 </li>
 <li>
  <div>
   <img  src="/static/imghw/default1.png"  data-src="images/4.jpg"  class="lazy"   alt="jquery implements simple waterfall flow layout" >
   <p>我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述</p>
  </div>
 </li>
</ul>
Copy after login

css

*{
 margin:0;
 padding: 0;
}
ul li{
 list-style: none;
}
#ul1{
 width: 1080px;
 margin: 100px auto 0;
}
li{
 width: 247px;
 float: left;
 margin-right: 10px;
}
li div{
 border:1px solid #000;padding:10px;
 margin-bottom:10px;
}
li div img{
 width: 225px;display: block;
}
Copy after login

The basic effect is as shown in the figure:

jquery implements simple waterfall flow layout

After the style is displayed correctly, delete the code in li.

Next, add it dynamically through ajax.

Where does the data come from?

The data interface of wookmark is used here.

http://www.wookmark.com/api/json/popular?page=1

Click on the url to get a json.

A lot of information. How to analyze?

Generally, you can read the documentation. But if you don’t have the document at hand, you can look at the link. What the hell is return.

function createUrl(num){
 return &#39;http://www.wookmark.com/api/json/popular?page=&#39;+num+&#39;&callback=?&#39;;
}
$(function(){
 $.getJSON(createUrl(1),function(data){
  console.log(data);
 })
})
Copy after login

The console print result is:

jquery implements simple waterfall flow layout

It turns out to be an array composed of 50 picture information. Each array element is a json. In this simple demo, you only need to get the preview attribute and title attribute for the time being.

Layout implementation

One of the keys is to determine the shortest li. In fact, we need the index value of the shortest height li.

//找出高度最小li的索引值
function getShortestLi(){
 var shortest=0;
 for(var i=1;i<4;i++){
  if($(&#39;li&#39;).eq(i).height()<$(&#39;li&#39;).eq(shortest).height()){
   shortest=i;
  }
 }
 return shortest;
}
Copy after login

Then there is the getJSON method

$(function(){
 $.getJSON(createUrl(1),function(data){
  //console.log(data);
  for(var i=0;i<dataArr.length;i++){
   var $html=$(&#39;<div><img  src="/static/imghw/default1.png"  data-src="&#39;+data[i].preview+&#39;"  class="lazy"   alt="jquery implements simple waterfall flow layout" ><p>&#39;+data[i].title+&#39;</p></div>&#39;);
   //console.log($(&#39;li&#39;).eq(getShortestLi()).height())
   $(&#39;li&#39;).eq(getShortestLi()).append($html);
  };
  console.log([$(&#39;li&#39;).eq(0).height(),$(&#39;li&#39;).eq(1).height(),$(&#39;li&#39;).eq(2).height(),$(&#39;li&#39;).eq(3).height()])
 })
})
Copy after login

Load it again and the layout will come out. Simple and beautiful.

jquery implements simple waterfall flow layout

At this point, everything looks fine. But there's a fatal problem lurking.

The for loop is causing trouble?

Look at the console.log information. For analysis, I put the heights of the four li's into an array:

The 50 pictures are divided into 4 columns. The average height must be three to four thousand pixels at least.

At the end of the loop, the end point judged by the program is only an outrageous 1,000 px, because the image loading process is slower than the for loop execution speed. Although the display in the demo is normal, this kind of code can cause work accidents when the network speed is not good.

Idea 1: You can determine whether the image is loaded.

You can use a timer to monitor it, and then use recursion to implement it. My plan is like this

var index=0;
function LoadPic(index){
 var $html=$(&#39;<div><img  src="/static/imghw/default1.png"  data-src="&#39;+data[index].preview+&#39;"  class="lazy"   alt="jquery implements simple waterfall flow layout" ><p>&#39;+data[index].title+&#39;</p></div>&#39;)
 $(&#39;li&#39;).eq(getShortestLi()).append($html);
 var oImg=$html.find(&#39;img&#39;);
 var t=setInterval(function(){
  if(oImg.height()!=0){//如果加载完了。
   clearInterval(t);
   //console.log([$(&#39;li&#39;).eq(0).height(),$(&#39;li&#39;).eq(1).height(),$(&#39;li&#39;).eq(2).height(),$(&#39;li&#39;).eq(3).height()])
   if(index<50){
    return LoadPic(index+1);
   }else{
    return false;
   } 
  }else{
   console.log(&#39;wait&#39;)
  }
 },50)//每隔50ms监听一次
}
LoadPic(0);
Copy after login

However, from the perspective of user experience, wait until a picture is loaded before proceeding. One load is unfriendly. Data providers should directly process the height of the image on the server and return it in json data. When the Internet speed is very slow, you have to wait for a long time, and then all the pictures come out all of a sudden. Don’t you think it’s weird? Especially third-party interfaces. Once it fails to load, there is a big problem.

Fortunately, the third party provides the width and height information of the image.

So you can still have a for loop. In the returned data, there are width and height values. Using them, you can achieve fixed width (255px) and fixed height (original height multiplied by a ratio).

$(function(){
 $.getJSON(createUrl(1),function(data){
  console.log(data);
  for(var i=0;i<data.length;i++){
    //console.log(data[i].preview);
    var $html=$(&#39;<div><img  src="/static/imghw/default1.png"  data-src="&#39;+data[i].preview+&#39;"  class="lazy"   alt="jquery implements simple waterfall flow layout" ><p>&#39;+data[i].title+&#39;</p></div>&#39;)
    $(&#39;li&#39;).eq(getShortestLi()).append($html);
     
    $html.find(&#39;img&#39;).css(&#39;height&#39;,(data[i].height*225/data[i].width)+&#39;px&#39;);
    $html.find(&#39;img&#39;).css(&#39;width&#39;,&#39;225px&#39;); 
   };
  //console.log([$(&#39;li&#39;).eq(0).height(),$(&#39;li&#39;).eq(1).height(),$(&#39;li&#39;).eq(2).height(),$(&#39;li&#39;).eq(3).height()])
 })
})
Copy after login

In fact, I personally think this is the simplest solution with the best user experience.

With the waterfall, we also need to flow

The logic of the flow

Pull down (scroll), the first li that enters the visual area at the bottom is loaded first.

jquery implements simple waterfall flow layout

In other words, when the sum of the height of the shortest li and the li to the top of the page is less than the sum of the height of the scroll bar and the height of the visual area, the li loading is triggered.

The height of li is easy to find. But how to find the shortest distance from li to the top of the page?

The native method can be implemented like this:

function getTop(obj){
 var iTop=0;
 while(obj){
  iTop+=obj.offsetTop;
  obj=obj.offsetParent;
 }//累加元素本身和自身所有父级高度偏移值
 return iTop;
}
Copy after login

But since this case uses jquery, it naturally has its own method.

obj.offset().top

Scroll event

The native implementation method is: window.onscroll=function(){...}

The implementation method of jquery is: $(window).scroll(function(){...})

Now verify whether there is any problem with the written code

(window).scroll(function(){
 var $li=$(&#39;li&#39;).eq(getShortestLi());
 var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;
 //console.log([$li.offset().top+$li.height(),document.documentElement.clientHeight+scrollTop])
 //如果li高度与li到页面顶部的高度之和<可视区高度+滚动距离
 if($li.offset().top+$li.height()<document.documentElement.clientHeight+scrollTop){
   alert(1);
 }
})
Copy after login

Run the code, When it is found that the first li to the bottom appears in the visible area, 1 will pop up to prove that it is available.

Because scrolling events are involved, getJSON related functions should be encapsulated as getList() for easy calling. So it needs to be readjusted.

The code at this time is like this:

//找出高度最小li的索引值
function getShortestLi(){
 var shortest=0;
 for(var i=1;i<4;i++){
  if($(&#39;li&#39;).eq(i).height()<$(&#39;li&#39;).eq(shortest).height()){
   shortest=i;
  }
 }
 return shortest;
}
function createUrl(num){
 return 'http://www.wookmark.com/api/json/popular?page='+num+'&callback=?';
}
function getList(n){
 $.getJSON(createUrl(n),function(data){
  //console.log(data);
  for(var i=0;ijquery implements simple waterfall flow layout

'+data[i].title+'

'); //console.log(data[i].height); $('li').eq(getShortestLi()).append($html); dataArr[i].height*=225/dataArr[i].width; $html.find('img').css('height',dataArr[i].height+'px'); $html.find('img').css('width','225px'); }; } $(function(){ var pageNum=1; getList(pageNum); $(window).scroll(function(){ var $li=$('li').eq(getShortestLi(); var scrollTop=document.documentElement.scrollTop||document.body.scrollTop; if($li.offset().top+$li.height()
Copy after login

In this way, it seems that it can be achieved. But when I looked at the console.log, I found another problem.

The logic of going to the toilet

在触发加载前提时,图片正在加载,期间动了滚动条,就又触发第二次加载,再动一下,就触发第三次,于是短短一瞬间,触发了n次加载。

那就做一个开关吧。

就跟公厕逻辑一样。n个人排队进一个坑位。外面的人想要进去首先得判断门是否锁上了。没锁才能进。进去之后第一件事把门锁上。等如厕完毕,门就打开。后面的人才能进

新设置一个开关bCheck,默认为true。

到触发加载条件时,还要判断bCheck是否为真(门开),为真时才能触发getList()(如厕)。否则return false(只能等)。

getList一开始就把bCheck设为false(如厕前先锁门)。等到getList回调函数执行到尾声。再把bCheck设为true(开门)。

这一段不贴代码了。

总有流完的一天。

当数据结束时(所有人上完厕所),就没有必要再进行加载了(自动把门锁上)。

所以在getJSON回调函数内锁门之后发现进来的是个空数组,那就进行判断,当获取到data的length为空时,直接returnfalse。那么bCheck就永远关上了。

全部代码如下:

//找出高度最小li的索引值
function getShortestLi(){
 var shortest=0;
 for(var i=1;i<4;i++){
  if($(&#39;li&#39;).eq(i).height()<$(&#39;li&#39;).eq(shortest).height()){
   shortest=i;
  }
 }
 return shortest;
}
function createUrl(num){
 return 'http://www.wookmark.com/api/json/popular?page='+num+'&callback=?';
}
var bCheck=false;
function getList(n){
 $.getJSON(createUrl(n),function(data){
  if(data.length==0){
   return false;
  }else{
   for(var i=0;ijquery implements simple waterfall flow layout

'+data[i].title+'

'); $('li').eq(getShortestLi()).append($html); $html.find('img').css('height',(data[i].height*225/data[i].width)+'px'); $html.find('img').css('width','225px'); }; } bCheck=true; }); } $(function(){ var pageNum=1; getList(pageNum); $(window).scroll(function(){ var $li=$('li').eq(getShortestLi()); var scrollTop=document.documentElement.scrollTop||document.body.scrollTop; //console.log([$li.offset().top+$li.height(),document.documentElement.clientHeight+scrollTop]) //如果li高度与li到页面顶部的高度之和<可视区高度+滚动距离 if($li.offset().top+$li.height()
Copy after login

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

更多jquery implements simple waterfall flow layout相关文章请关注PHP中文网!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

What should I do if I encounter garbled code printing for front-end thermal paper receipts? What should I do if I encounter garbled code printing for front-end thermal paper receipts? Apr 04, 2025 pm 02:42 PM

Frequently Asked Questions and Solutions for Front-end Thermal Paper Ticket Printing In Front-end Development, Ticket Printing is a common requirement. However, many developers are implementing...

Who gets paid more Python or JavaScript? Who gets paid more Python or JavaScript? Apr 04, 2025 am 12:09 AM

There is no absolute salary for Python and JavaScript developers, depending on skills and industry needs. 1. Python may be paid more in data science and machine learning. 2. JavaScript has great demand in front-end and full-stack development, and its salary is also considerable. 3. Influencing factors include experience, geographical location, company size and specific skills.

Demystifying JavaScript: What It Does and Why It Matters Demystifying JavaScript: What It Does and Why It Matters Apr 09, 2025 am 12:07 AM

JavaScript is the cornerstone of modern web development, and its main functions include event-driven programming, dynamic content generation and asynchronous programming. 1) Event-driven programming allows web pages to change dynamically according to user operations. 2) Dynamic content generation allows page content to be adjusted according to conditions. 3) Asynchronous programming ensures that the user interface is not blocked. JavaScript is widely used in web interaction, single-page application and server-side development, greatly improving the flexibility of user experience and cross-platform development.

How to merge array elements with the same ID into one object using JavaScript? How to merge array elements with the same ID into one object using JavaScript? Apr 04, 2025 pm 05:09 PM

How to merge array elements with the same ID into one object in JavaScript? When processing data, we often encounter the need to have the same ID...

The difference in console.log output result: Why are the two calls different? The difference in console.log output result: Why are the two calls different? Apr 04, 2025 pm 05:12 PM

In-depth discussion of the root causes of the difference in console.log output. This article will analyze the differences in the output results of console.log function in a piece of code and explain the reasons behind it. �...

How to achieve parallax scrolling and element animation effects, like Shiseido's official website?
or:
How can we achieve the animation effect accompanied by page scrolling like Shiseido's official website? How to achieve parallax scrolling and element animation effects, like Shiseido's official website? or: How can we achieve the animation effect accompanied by page scrolling like Shiseido's official website? Apr 04, 2025 pm 05:36 PM

Discussion on the realization of parallax scrolling and element animation effects in this article will explore how to achieve similar to Shiseido official website (https://www.shiseido.co.jp/sb/wonderland/)...

How to implement panel drag and drop adjustment function similar to VSCode in front-end development? How to implement panel drag and drop adjustment function similar to VSCode in front-end development? Apr 04, 2025 pm 02:06 PM

Explore the implementation of panel drag and drop adjustment function similar to VSCode in the front-end. In front-end development, how to implement VSCode similar to VSCode...

Is JavaScript hard to learn? Is JavaScript hard to learn? Apr 03, 2025 am 12:20 AM

Learning JavaScript is not difficult, but it is challenging. 1) Understand basic concepts such as variables, data types, functions, etc. 2) Master asynchronous programming and implement it through event loops. 3) Use DOM operations and Promise to handle asynchronous requests. 4) Avoid common mistakes and use debugging techniques. 5) Optimize performance and follow best practices.

See all articles