Hello everyone, I’m Daotin, captain of the front end, want to get more exciting content of the front end, follow me, unlock the new position of the front end growth.

Recent updates:

  • 4 Common Cross-domain Ajax Solutions (Easy to understand)
  • JS static type detection, has an internal flavor
  • Lazy image loading in 3 minutes

The following text:

It takes about 8 minutes to read. It is recommended that you collect it before you see it.

What is a picture waterfall flow

Using the layout of a petal web page, you can see what the waterfall looks like:

Simply put, there are many pictures on the page, each of the same width, but different height, so scattered out of n columns looks like a waterfall, so there is a waterfall flow picture.

Realize the principle of

1. The first way

The first method assumes that the image has a fixed width but variable columns (depending on the screen size).

Through the above introduction, we know that to achieve the waterfall flow is the premise of the same width (if 100px), the height can be different.

We first set the number of columns (say 4), so only 4 images can be placed in the first row, and then place the height of each image in an array (say, heightArr = [100,50, 200,30]). When we place the next image in the array, we need to determine which height is the smallest (in this case, 30), and then we need to know the index of the array (in this case, I = 3), and then we can position the image:

{
    position: absolute;
    left: i*100 + 'px';
    top: 30 + 'px'
}
Copy the code

Do this for the rest of the image.

The implementation code

Below is the raw code without processing, there are many blanks between the pictures, which affects the appearance.

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .box {
            position: relative;
        }
        img {
            width: 200px;
            vertical-align: top;
            padding: 5px;
        }
</style>
</head>
<body>
    <div class="box">
        <img src="./images/img/2-.jpg" alt="">
        <img src="./images/img/3-.jpg" alt="">
        <img src="./images/img/4-.jpg" alt="">
        <img src="./images/img/5-.jpg" alt="">
        <img src="./images/img/6-.jpg" alt="">
        <img src="./images/img/7-.jpg" alt="">
        <img src="./images/img/8-.jpg" alt="">
        <img src="./images/img/9-.jpg" alt="">
        <img src="./images/img/10-.jpg" alt="">
        <img src="./images/img/11-.jpg" alt="">
        <img src="./images/img/12-.jpg" alt="">
        <img src="./images/img/13-.jpg" alt="">
        <img src="./images/img/14-.jpg" alt="">
        <img src="./images/img/15-.jpg" alt="">
        <img src="./images/img/16-.jpg" alt="">
    </div>
</body>
</html>

Copy the code

Here is the processed code:

<script>
    $(function () {
        // Get the image width (200px)
        let imgWidth = $('img').outerWidth(); / / 200

        waterfallHandler();

        // Waterfall flow processing
        function waterfallHandler() {
            // Get the number of columns in the image
            let column = parseInt($(window).width() / imgWidth);

            // The height array
            let heightArr = [];
            for(let i=0; i<column; i++) {
                heightArr[i] = 0;
            }

            // Traverse all images for positioning processing
            $.each($('img'), function (index, item) {
                // The height of the current element
                let itemHeight = $(item).outerHeight();
                // The minimum height of the height array
                let minHeight = Math.min(... heightArr);// The index of the lowest height of the height array
                let minIndex = heightArr.indexOf(minHeight);

                $(item).css({
                    position: 'absolute'.top: minHeight + 'px'.left: minIndex * imgWidth + 'px'
                });

                heightArr[minIndex] += itemHeight;
            });
        }

        // Window size changed
        $(window).resize(function () {
            waterfallHandler();
        });
    });
</script>

Copy the code

2. The second way

The second approach assumes that the columns are a fixed number and the image adaptively scales to the width of the screen.

This way because the picture can be scaled, width and height is not good to determine, so it is not easy to use the positioning method.

So we can do this, now that we know the columns, let’s make a container for each column. Then go through the picture, the picture into the container of the smallest height can be.

Here we use JS to add images, rather than writing them in HTML.

The implementation code

<! DOCTYPEhtml>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        ul li {
            list-style: none;
            float: left;
        }
</style>
</head>

<body>
</body>
<script src="./jquery.min.js"></script>
<script>
    $(function () {
        const COLUMN = 4; / / 4 columns
        let arr = []; // Store 4 columns li
        let minHeight = [] // Store the height of 4 columns

        create();

        function create() {
            // Create ul li as a container for each column
            $("<ul></ul>").appendTo($("body")).css("width"."100%");
            for (let i = 0; i < COLUMN; i++) {
                var li = document.createElement("li");
                $(li).appendTo($("ul"))
                    .css({
                        "width": "24%"."margin": "0 0.5%." "
                    });
                arr.push(li);
                // console.log(arr);
                minHeight.push(0);
            }
            createImg();
        }

        function createImg() {
            let img = new Image();
            img.num = 2;
            img.src = `./images/img/${img.num}-.jpg`; // The pattern of the source image is 2-.jpg 3-.jpg 4-.jpg...
            $(img).css("width"."100%");
            // When the image is loaded
            $(img).on("load", loadHandler);
        }

        function loadHandler() {
            // The minimum value of the height array
            let min = Math.min.apply(null, minHeight);
            // The minimum index of the height array
            let minIndex = minHeight.indexOf(min);
            // Clone a picture
            let im = this.cloneNode(true);
            // Place the image in the container corresponding to the minimum index
            arr[minIndex].append(im);
            // Update the height of the container with the minimum index
            minHeight[minIndex] += im.getBoundingClientRect().height;

            this.num++;

            // The number of pictures is only 79
            if (this.num > 79) {$(this).off("load", loadHandler);
                return;
            }
            this.src = `./images/img/The ${this.num}-.jpg`; }});</script>

</html>

Copy the code

(after)

Public account background reply [waterfall flow] to obtain the source code package of this article.


Original is not easy, if you feel helpful, also welcome to like, share, add collection!

It is said that the person who praises will be promoted and get a raise in a month, marry Bai Fumei, and walk to the peak of life ~