Hello, brave friends, Hello, everyone, I am your mouth strong king xiaowu, healthy body, brain is not sick.

I have a wealth of hair loss techniques that can make you a veteran.

A look will be a waste is my main purpose, food to scratch my feet is my characteristics, humble with a trace of strong, stupid people have silly fortune is the biggest comfort to me.

Welcome to the new Village project – Picture waterfall flow.

preface

The objective of this paper is to achieve horizontal and vertical waterfall flow; Horizontal using Flex layout, vertical provides Absolute Absolute positioning and Grid layout two solutions; The real interface request is used in data, and the picture is stored after crawler. Optimization of lazy loading and anti – shake, reduce resource consumption while enhancing user experience.

👉 Put the code link in both hands

Demo website:

Vertical waterfall Flow – Demo url

Horizontal Waterfall Flow – Demo url

Effect:

Tips: Pictures are crawler crawler [source: wallhaven. Cc], filter size is 200K, actual work can access pictures of different specifications, waterfall flow display small picture, preview in loading high definition large picture.

Basic gleanings

This part of the content is the knowledge point needed in this article, if you need to expand, please consult relevant information by yourself

Lazy loading

Waterfall flow is a massive load of images on demand; The browser cannot process all the tasks at one time, resulting in a lag, a blank screen and a waste of resources.

Lazy loading is the optimization of picture loading time, that is, after the picture enters the field of view, it is loaded;

🤔 The idea is as follows:

/* -- viewable area height -- **/
winHeight = window.innerHeight

/* -- page slide distance -- **/
scrollTop = document.body.scrollTop || document.documentElement.scrollTop

/* -- distance from the top of the element to the top of the browser -- **/
offsetTop = imageNode.offsetTop

/* -- load time -- **/
offsetTop < scrollTop + winHeight

/* -- load the image -- **/
imageNode.src = imageNode.getAttribute('data-src')
Copy the code

Throttling and anti-shaking

In this project, the author only uses the basic anti-shake. Here, the optimization of throttling and anti-shake is to expand the knowledge.

👉 throttling

Core idea: The first one counts

Throttling means ignoring subsequent callback requests for a period of time;

function throttle(fn, interval) {
  let last = 0;                    // Last callback timestamp
  return function () {
    let now = +new Date(a);// This callback time stamp
    if (now - last >= interval) {  // This time - last time >= time interval, then trigger callback
      last = now;                  // reassign
      fn.apply(this.arguments);   // Execute the function}}}Copy the code

👉 stabilization

Core idea: The last one counts

The so-called shake, refers to a period of time, if the new callback, then re-timing;

function debounce(fn, delay) {
  let timer = null;                  / / initialization
  return function () {
    if (timer) clearTimeout(timer);  // Clear the timer repeatedly within the delay time
    timer = setTimeout(function () { // Set the timer
      fn.apply(this.arguments);     // Trigger function}, delay); }}Copy the code

👉 throttling optimization anti-shake

Avoid frequent operations but no response, to create a bottom line tremble

function debounce(fn, delay) {
  let last = 0;
  let timer = null;

  return function () {
    let now = +Date.now();
    if (now - last >= delay) {
      last = now;
      fn.apply(this.arguments);
    } else {
      if (timer) clearTimeout(timer);
      timer = setTimeout(function () {
        last = now;
        fn.apply(this.arguments); }, delay); }}}Copy the code

Grid layout

Tips: This is just for the knowledge points used in the project

Using the above selected element as an example, the following code:

.grid-wrapper {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px.1fr));
  grid-auto-rows: 10px;
  grid-auto-flow: row dense;
  gap: 0 10px;
}
.grid-item {
  width: 100%;
  height: auto;
  grid-row-start: auto;
  grid-row-end: span 22;
}
.grid-item img {
  object-fit: cover;
  width: 100%;
  height: auto;
  background-color: #eee;
  box-sizing: border-box;
  border: 1px solid #ccc;
}
Copy the code
  1. The grid – the template – the columns and the grid – the template – rows

Grid-template-columns: 200px 100px 200px; grid-template-columns: 200px 100px; The representation is divided into three columns, 200px, 100px and 200px respectively.

-> repeat(number of repeats, child element width)

-> auto-fit: the width is fixed and the quantity is adaptive

-> Minmax (150px, 1fr) -> Minmax (150px, 1fr) -> Minmax (150px, 1fr) -> Minmax (150px, 1fr) -> Minmax (150px, 1FR)

  1. Grid-auto-rows, grid-row-start, grid-row-end
/* Parent element **/
grid-auto-rows: 10px;
/* Child element **/
grid-row-start: auto;
grid-row-end: span 22; // The number of cells must be an integerCopy the code

It means that each cell is 10px, the child element starts at an adaptive position and occupies 22 cell heights, i.e. 220px

Tips: I set 10px to make the grid of the screenshot clearer. In practice, I set the minimum cell to 1px

  1. grid-auto-flow

This property is the arrangement, set to ROW, i.e. horizontal arrangement; The second parameter dense means to fill as much as possible and reduce white space (equivalent to absolute layout insertion, see below).

  1. gap

Row spacing and column spacing, gap: 0 10px; Indicates a column spacing of 10px

Function implementation

Interface:

👉 click me to view the interface code

Tips: Images are from Wallhaven. Cc and obtained by crawlers

Data format:

data = [
  {
    id: 1,
    image_url: "xxx",
    size: "xxx",
    title: "xxx",
    width: "xxx",
    height: "xxx"},... ]Copy the code

Transverse waterfall flow

👉 click here to see the demo

See the full code at 👉

Features: Fixed height and variable width

Flex layout, use flex-wrap, use flex-grow to allocate the remaining space, and achieve adaptive goals.

Longitudinal waterfall flow

👉 click here to see the demo

Features: Fixed width variable height

Provide two ideas, respectively for Absolute Absolute positioning and Grid Grid layout

Absolute solution

👉 I see the complete code – Absolute

Goal:

  1. Append top and left to each element;

  2. Absolute is removed from the document flow, so you append height to the parent element.

✍️ Child element width calculation

The first step is to determine the width and number of columns of each child element

For better effect, let’s simulate the minmax mentioned above

Two known setpoints: [gap] [baseWidth]

The following information can be listed:

  • N * (baseWidth + x) + (n + 1) * gap = width, where n is the number of columns, x is the allocation length, and width is the screen width

  • N is a positive integer

  • x > 0 & x < baseWidth

  • Let n be maximized based on the above conditions

We substitute n into x to find the optimal solution, and the code is as follows:

✍ ️ layout

After we know the width, height and number of columns of the child elements, we append top and left attributes to them

Append attributes to the first row of elements as follows:

itemNode.style.top = `${gap}px`;
itemNode.style.left = `${gap + i * (itemWidth + gap)}px`;
Copy the code

Where gap is the spacing; ItemWidth is the width of the child element just calculated; I is the index of the loop, i.e. the number of elements;

How to determine the top of the elements in the second row of ❓

👉 Based on the height of each column, we define a column length heights array to store the height of each column

What about the order ❓

👉 images vary in length, resulting in some columns being long and some columns being short, as shown below

Therefore, each time you push the element to the smallest height of the column to achieve the best visual effect

The implementation is as follows:

Math.max(… Heights is the height appended to the parent element

The Grid plan

See the full code at 👉 — Grid

The idea has been explained one by one in the basic pick-up part, among which grid-row-end needs to be obtained by calculation; Dense can achieve the shortest height of priority filling;

Remaining code snippets

Lazy loading

Calculates the height of the child element

Image error handling

Image stabilization

conclusion

  • When the picture is too large, the picture of different sizes should be stored. When the waterfall flow shows the small picture, and when the preview shows the large picture

  • Absolute scheme is not resized, you can add it by yourself (the author uses it in mobile terminal and Grid scheme in PC terminal)

  • The aspect ratio of the image is necessary, otherwise the image will not look good before loading