6
Author: God Q Superman Translator: Front-end Xiaozhi Source: medium

If you have dreams and dry goods, you can search for [Great Move to the World] on WeChat and pay attention to this Shawanzhi who is still washing dishes in the early hours of the morning.

This article GitHub https://github.com/qq449245884/xiaozhi has been included, there are complete test sites, materials and my series of articles for interviews with first-line manufacturers.

When I was working on a project a while ago, each set of data had to go through a huge calculation before rendering the calculated results on the page. However, if the data found on a single page exceeded about 5, You will need to wait for a period of time before you can see the results appear on the screen.

Later, in order to solve this poor user experience, I used the Lazy Loading mentioned in the title to deal with it. To put it simply, although there are 10 pieces of data to be displayed, since a page can only display 2 to 3 pieces of data, I will first calculate the 2 to 3 pieces of data and then display them, and the rest of the data will wait for the user Scroll down to resume the display so it doesn't take too long.

Then, as a front-end engineer, after thinking of this solution, of course, I went to Github to find a simple and convenient component to solve it😂, and the vue-scroll-loader found in the end is very easy to use and has very little code, so just After dealing with the issue, let's see how it implements Lazy Loading internally, so I see the Intersection Observer API that is mainly talked about today!

image.png

Intersection Observer API

So what exactly is the Intersection Observer API? Why can it be used to implement Lazy Loading? In the words of MDN:

The Intersection Observer API provides a way to asynchronously detect changes in the intersection of a target element with an ancestor element or viewport.

Simply put, it means that as long as you use the Intersection Observer API, you can monitor when the target element appears or leaves on the screen, and execute the callback method you give it . See how to use it below!

Instructions

Start with simple HTML and CSS, and the main goal is to place the div where it only appears when you scroll down:

 body {
  height: 1000px;
}

.box {
  width: 100px;
  height: 100px;
  background: #000;
  position: absolute;
  top: 500px;
}
 <body>
  <div class="box"></div>
</body>

Then we use the observe method of the Intersection Observer API to pass the object to be monitored div as a parameter, and use callback to appear and leave it in the div When giving a message:

 const intersectionObserver = new IntersectionObserver(
  () => { console.log('hi'); }
);

intersectionObserver.observe(
  document.querySelector('.box')
);

The result of execution will look like this:

When the Intersection Observer API executes callback , it will also give you a Array , Array are all the elements that are being monitored, we can get from these elements isIntersecting To determine whether the current element appears in the screen or leaves the screen:

 const intersectionObserver = new IntersectionObserver(
  (entries) => {
    if (entries[0].isIntersecting) {
      console.log('我進來了!');
    } else {
      console.log('我又出去了!');
    }
  }
);

intersectionObserver.observe(
  document.querySelector('.box')
);

Results of the:

Finally, when you no longer need to continue to monitor elements, you can use unobserve to cancel the monitoring, and use it just like the monitoring used observe , give it the elements that it does not need to monitor. :

 intersectionObserver.unobserve(
  document.querySelector('.box')
);

The above is the basic usage of the Intersection Observer API, of course, there are other more careful settings (you can see the introduction of MDN ), but if you want to complete a simple Lazy Loading, it is more than enough to use the above methods. !

Lazy Loading

The way to implement Lazy Loading in the Intersection Observer API is to put a small animation loading at the end of the data list, and then just monitor the small animation. When it appears on the page, use the Intersection Observer API's callback Load more data.

First of all, simply write the data to be displayed <ul> , and the element to be monitored. I will not do a small animation here, but directly use Loading… instead of text:

 <body>
  <ul class="list"></ul>
  <div class="loading">Loading...</div>
</body>

It should be noted that the monitored element must be at the bottom of the loaded data! Otherwise it will not be monitored for "appearing on the page" (notes will be explained in more detail below).

The JavaScript part of the code is posted first, and then explained below:

 const data = Array.from(Array(200)).map(
  (_value, index) => `第 ${index + 1} 筆資料`
);

const render = () => {
  const list = document.querySelector('.list');

  const LOAD_DATA_COUNT = 50;
  const startLoadIndex = list.childNodes.length;
  const endLoadIndex = startLoadIndex + LOAD_DATA_COUNT;
  for (let i = startLoadIndex; i < endLoadIndex; i++) {
    if (data[i]) {
      const text = document.createTextNode(data[i]);
      const li = document.createElement('li');
      li.appendChild(text);
      list.appendChild(li);
    }
  }
  
  if (endLoadIndex >= data.length) {
    const loading = document.querySelector('.loading');
    loading.style.display = 'none';
    intersectionObserver.unobserve(loading);
  }
};

render();

const intersectionObserver = new IntersectionObserver(
  (entries) => {
    if (entries[0].isIntersecting) {
      setTimeout(render, 1000);
    }
  }
);

intersectionObserver.observe(
  document.querySelector('.loading')
);
  1. First use the loop to generate 200 fake data
  2. Write a method of render , add the data that has not been loaded in a loop, and add 50 pieces of data at a time here
  3. After adding data in render , to judge whether the current added index is greater than the total number of data, if there is, it means that all data is displayed, so it is hidden loading , and remove the Intersection Observer API's monitoring of loading
  4. After all, there is still data on the screen at the beginning! So manually execute the first render method
  5. Use the Intersection Observer API to monitor loading , as soon as it appears on the screen (meaning that the user has finished reading the current data, it will be executed render . Here for the real render feel, I use setTimeout to delay 1 seconds

The effect of execution will look like this:

But there is another point to note. For the above example, if the Intersection Observer API executes the render because loading appears in the page, but the amount of data after rendering is not enough to loading Move out of the screen, then loading will stay in the screen, not "in the screen", so the Intersection Observer API will not trigger render Load more data.

Finally, let's look at support. The support of ntersection Observe API is not bad, but if the product has to take into account the customer base of IE, it can't be used. 😅

In the end, I still feel that I have learned a lot of interesting things from open source projects. I also recommend that you take a peek at the source code behind when you use some components. 😂

~End, I'm Shawanzhi, in the new year, let's wash and refresh together! !


The bugs that may exist after the code is deployed cannot be known in real time. In order to solve these bugs afterwards, a lot of time is spent on log debugging. By the way, I recommend a useful bug monitoring tool , Fundebug .

Original: https://medium.com/starbugs/%E7%94%A8%E5%8E%9F%E7%94%9F%E7%9A%84-javascript-intersection-observer-api-%E5%AF% AE7%8F%BE-lazy-loading-6bedccd0950

comminicate

If you have dreams and dry goods, you can search for [Great Move to the World] on WeChat and pay attention to this Shawanzhi who is still washing dishes in the early hours of the morning.

This article GitHub https://github.com/qq449245884/xiaozhi has been included, there are complete test sites, materials and my series of articles for interviews with first-line manufacturers.


王大冶
68.1k 声望105k 粉丝