Jquery implements simple waterfall stream layout and jquery waterfall Layout

Source: Internet
Author: User

Jquery implements simple waterfall stream layout and jquery waterfall Layout

Is the principle that will be explained at the beginning

Waterfall flow layout has two types: fixed column and non-fixed column. The first implementation is described here.

The fixed column feature is that no matter how the page scales, the total number of columns in each row is consistent.

A waterfall stream with four columns in a row has four li labels in terms of layout. Use Certain events (such as the number of pixels in the scroll bar), read them, and dynamically Add the data to the page.

The data addition principle is not based on the li index value, but dynamically added based on the column with the shortest height in each column. Otherwise, the page may be ugly (the height of the left and right is not uniform ).

The instance involves ajax methods. It can run in a server environment.

No more nonsense. Directly upload the style.

<Ul id = "ul1"> <li> <div>  <p> I am a text description, I am a text description, and I am a text description. text description: text description </p> </div> </li> <div>  <p> i'm a text description, I'm a text description </p> </div> </li> <div>  <p> I'm a text description, I'm a text description </ p> </div> </li> <div>  <p> I am a text description. i'm a text description, I'm a text description, I'm a text description </p> </div> </li> </ul>

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;}

Basic results

After the style display is correct, delete the code in li.

Next we will use ajax to dynamically add.

Where does the data come from?

Here we use the data interface of wookmark.

Http://www.wookmark.com/api/json/popular? Page = 1

Click the url to obtain a json string.

A large amount of information. How to analyze?

Generally, you can read the document. If you do not have a document, you can check the link. What is returned.

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

The result is as follows:

It was originally an array consisting of 50 image information. Each array element is a json. In this simple demo, you only need to obtain the preview and title attributes.

Layout implementation

One of the key lies in determining the shortest li. In fact, we need the shortest li index value.

// Find the index value of the minimum height li function getShortestLi () {var shortest = 0; for (var I = 1; I <4; I ++) {if ($ ('lil '). eq (I ). height () <$ ('lil '). eq (shortest ). height () {shortest = I ;}return shortest ;}

Then the getJSON method is used.

$(function(){ $.getJSON(createUrl(1),function(data){  //console.log(data);  for(var i=0;i<dataArr.length;i++){   var $html=$('<div><p>'+data[i].title+'</p></div>');   //console.log($('li').eq(getShortestLi()).height())   $('li').eq(getShortestLi()).append($html);  };  console.log([$('li').eq(0).height(),$('li').eq(1).height(),$('li').eq(2).height(),$('li').eq(3).height()]) })})

Load the file and check the layout. Simple and beautiful.

Everything looks good. However, there is a fatal problem.

What's wrong with the for loop?

Check the console. log information. For analysis, I put the Four li heights into an array:

50 images are divided into 4 columns, with an average height of 3000 or 4000 pixels.

By the end of the loop, the program determines that the end point is only more than 1000 million px, because the image loading process is slower than the for loop execution speed. Although the display in the demo is still normal, this Code may 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 listen and implement it recursively. My solution is as follows:

Var index = 0; function LoadPic (index) {var $ html = $ ('<div>  <p>' + data [index]. title + '</p> </div>') $ ('lil '). eq (getShortestLi ()). append ($ html); var oImg = $ html. find ('img '); var t = setInterval (function () {if (oImg. height ()! = 0) {// if the load is complete. ClearInterval (t); // console. log ([$ ('lil '). eq (0 ). height (), $ ('lil '). eq (1 ). height (), $ ('lil '). eq (2 ). height (), $ ('lil '). eq (3 ). height ()]) if (index <50) {return LoadPic (index + 1) ;}else {return false ;}} else {console. log ('wait') }}, 50) // listens every 50 ms} LoadPic (0 );

However, from the perspective of user experience, it is unfriendly to wait until a graph is loaded and then perform the next loading. The data provider should directly process the Image Height on the server and return the json data. When the network speed is very slow, I have to wait for a long time, and then all the pictures are coming out. Don't you think it's weird? Especially third-party interfaces. A major problem occurs when the data cannot be loaded.

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

Therefore, the for loop is still available. The returned data contains the width and height values. You can use them to achieve a fixed width (255px) and a fixed height (the 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=$('<div><p>'+data[i].title+'</p></div>')    $('li').eq(getShortestLi()).append($html);        $html.find('img').css('height',(data[i].height*225/data[i].width)+'px');    $html.find('img').css('width','225px');    };  //console.log([$('li').eq(0).height(),$('li').eq(1).height(),$('li').eq(2).height(),$('li').eq(3).height()]) })})

In fact, I personally think This is the simplest and best user experience solution.

With the waterfall, you still need to stream

Stream Logic

Scroll down, and enter the li in the visible area at the First Bottom.

In other words,The sum of the shortest li height and the li to the top of the pageLessSum of the scroll bar height and the visible area height.

Li is highly demanding. But how can I find the shortest distance from li to the top of the page?

The native method can be implemented as follows:

Function getTop (obj) {var iTop = 0; while (obj) {iTop + = obj. offsetTop; obj = obj. offsetParent;} // return iTop ;}

However, in this case, jquery is used.

obj.offset().top

Rolling event

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

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

Verify that the code is correct.

(Window ). scroll (function () {var $ li = $ ('lil '). eq (getShortestLi (); var scrollTop=document.doc umentElement. scrollTop | document. body. scrollTop; // lele.log({{li.offset().top;{li.height(,document.doc umentElement. clientHeight + scrollTop]) // if the sum of the li height and the li height to the top of the page <visible area height + rolling distance if ($ li. offset (). top + $ li. height () <document.doc umentElement. clientHeight + scrollTop) {alert (1 );}})

When you run the code and find that the first li is in the visible area, the pop-up 1. Prove it is available.

Because rolling events are involved, the getJSON functions should be encapsulated as getList () for convenient calling. So you need to adjust it again.

The Code is as follows:

// Find the index value of the minimum height li function getShortestLi () {var shortest = 0; for (var I = 1; I <4; I ++) {if ($ ('lil '). eq (I ). height () <$ ('lil '). 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; I <data. length; I ++) {var $ html = $ ('<div>  <p>' + data [I]. title + '</p> </div>'); // console. log (data [I]. height); $ ('lil '). eq (getShortestLi ()). append ($ html); dataArr [I]. height * = 225/dataArr [I]. width; $html.find('img'hangzhou.css ('height', dataArr [I]. height + 'px '); $html.find('img').css ('width', '25px') ;}$ (function () {var pageNum = 1; getList (pageNum ); $ (window ). scroll (function () {var $ li = $ ('lil '). eq (getShortestLi (); var scrollTop=document.doc umentElement. scrollTop | document. body. scrollTop; if ($ li. offset (). top + $ li. height () <document.doc umentElement. clientHeight + scrollTop) {pageNum ++; console. log (pageNum); getList (pageNum );}})})

In this way, it seems to be feasible. However, you can see the console. log in the console and find the problem.

Restroom Logic

When loading is triggered, the image is being loaded. When the scroll bar is moved, the second loading is triggered. Then, the third loading is triggered. In a short moment, triggered n times of loading.

Make a switch.

Just like the logic of public toilets. N people lined up in a trap. People outside should first determine whether the door is locked. No lock is required. First, lock the door. When the restroom is finished, the door opens. Talent behind

Set a new switch bCheck. The default value is true.

When the loading condition is triggered, you must determine whether bCheck is true (door open). If it is true, getList () can be triggered (such as toilet ). Otherwise, return false (wait only ).

GetList sets bCheck to false at the beginning (lock the door before going to the toilet ). Wait until the execution of the getList callback function ends. Set bCheck to true (open the door ).

This paragraph does not post code.

There will always be one day of streaming.

When the data ends (everyone goes to the toilet), there is no need to load the data (automatically lock the door ).

Therefore, if an empty array is found after the getJSON callback function locks the door, the system determines that when the obtained data length is null, the system will directly returnfalse. BCheck will be closed forever.

The Code is as follows:

// Find the index value of the minimum height li function getShortestLi () {var shortest = 0; for (var I = 1; I <4; I ++) {if ($ ('lil '). eq (I ). height () <$ ('lil '). 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; I <data. length; I ++) {// console. log (data [I]. preview); var $ html = $ ('<div>  <p>' + data [I]. title + '</p> </div>'); $ ('lil '). eq (getShortestLi ()). append ($ html); $html.find('img').css ('height', (data [I]. height * 225/data [I]. width) + 'px '); $html.find('img'0000.css ('width', '25px') ;};} bCheck = true ;});} $ (function () {var pageNum = 1; getList (pageNum); $ (window ). scroll (function () {var $ li = $ ('lil '). eq (getShortestLi (); var scrollTop=document.doc umentElement. scrollTop | document. body. scrollTop; // lele.log({{li.offset().top;{li.height(,document.doc umentElement. clientHeight + scrollTop]) // if the sum of the li height and the li height to the top of the page <visible area height + rolling distance if ($ li. offset (). top + $ li. height () <document.doc umentElement. clientHeight + scrollTop) {if (bCheck) {bCheck = false; pageNum ++; // console. log (pageNum); getList (pageNum) ;}else {return false ;}}})})

The above is all the content of this article. I hope this article will help you in your study or work. I also hope to provide more support to the customer's home!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.