Pictures are lazy to load, that is, when scrolling a page, pictures are not loaded when they do not appear in the visible area, but only when they appear in the visible area.
Idea: Through the above paragraph, you need to know to lazy load pictures:
- Bind Scroll Event
- Visible Window Height (VH)
- Picture Element Distance Visible Local Top Distance (EH)
- How to load pictures
When the VH is larger than the EH, the picture appears in the visible window, and vice versa.
How do I load pictures?We can bind any property for the img tag that is not its property name and use the picture path as its property value, for example:
<img data-src="./img/ec6c60c8c5de6d7fa899807cfa8d46f1.jpeg" alt=""> <img imgUrl="./img/ec6c60c8c5de6d7fa899807cfa8d46f1.jpeg" alt=""> <img aabbc="./img/ec6c60c8c5de6d7fa899807cfa8d46f1.jpeg" alt="">
Yes, here we use
<img data-src="./img/ec6c60c8c5de6d7fa899807cfa8d46f1.jpeg" alt="">
For example:
First you need to get the collection of DOM objects for the img element
let imgs = document.querySelectorAll('img')
Traverse through the img's collection of DOM objects to get each img's DOM object
imgs.forEach(item => { // Get and compare the distance to the top of the visible area and the height of the visible area for each img distance if (item.getBoundingClientRect().top < window.innerHeight) { // Gets the attribute value whose element attribute is data-src and assigns it to the SRC attribute of the imgDOM instance item.setAttribute('src',item.getAttribute('data-src')) } })
The height of the element from the top of the viewport is obtained by getBoundingClientRect().top of the DOM object, and the height of the viewport is obtained by window.innerHeight.
item.getAttribute('data-src'): Indicates the attribute value to get the data-src attribute of the name on the DOM object.
item.setAttribute(attributeName,attributeValue): Indicates that the attributeValue value is assigned to the attributeName attribute as the attribute value.
At this point we need to bind a scroll event, which is bound to window and triggers whenever a scroll bar scrolls:
let imgs = document.querySelectorAll('img') // Bind scroll events for window s window.addEventListener('scroll', (e) => { // Traverse through the img's collection of DOM objects to get each img's DOM object mgs.forEach(item => { // Get and compare the distance to the top of the visible area and the height of the visible area for each img distance if (item.getBoundingClientRect().top < window.innerHeight) { //Gets the attribute value whose element attribute is data-src and assigns it to the SRC attribute of the imgDOM instance item.setAttribute('src',item.getAttribute('data-src')) } }) })
The problem with this is that each scroll triggers a scroll event, which can cause excessive resource loading and waste resources.
There are three solutions given here.
2. Consider compatibility: use anti-shake or throttling
Here's an example using throttling (anti-shake can do it yourself)
<script> // 1 Get the DOM object of the img element let imgs = document.querySelectorAll('img') // Bind scroll events for window s window.addEventListener('scroll', imgLazyLoading()) function imgLazyLoading() { let timer return () => { if (timer) { return; } timer = setTimeout(() => { imgs.forEach(item => { // Get and compare the distance to the top of the visible area and the height of the visible area for each img distance if (item.getBoundingClientRect().top < window.innerHeight) { // Gets the attribute value whose element attribute is data-src and assigns it to the SRC attribute of the imgDOM instance item.setAttribute('src', item.getAttribute('data-src')) } }) timer = null }, 500) } } </script>
Throttling or anti-shaking can also cause images to load too much, but this saves browser resources more than not.
3, regardless of compatibility
Use the IntersectionObserver constructor (which is provided by browsers and not supported by some browsers).This is cross-observation possible. What is cross-observation?It is what happens when the target element and the visual window cross-localize, and what happens when no cross-localization occurs.
The IntersectionObserver constructor provides two methods for observing what is performed when the target element intersects and what is not.
observe(DOM node): Observe whether a node crosses
unobserve(DOM node): Cancel observation
Create an instance:
let observer=new IntersectionObserver(callBack)
callBack is a callBack function that executes twice, once when the target element intersects the visual window, and once when no intersection occurs (called once when seen, once when invisible)
The callBack callback function receives a parameter that contains an array of information about the DOM node being observed and the state of the observation, where what we need is an array of items in each array:
target: the observed DOM node instance
isIntersecting: Whether or not it is observed, when it is observed, we only need to cancel the observation by unobserve(DOM node).The completion code is:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <style> div { height: 100vh; width: 1000px; position: relative; top: 50%; left: 50%; transform: translate(50% 50%); } img { padding-top: 50px; margin-bottom: 50px; height: 500px; width: 500px; background-repeat: no-repeat; background-size: 100% 100%; display: inline-block; border-top: 2px solid red; } </style> <body> <div> <p>1111111111111111111111111111111111111111111111111111111111111111</p> <p>22222222222222222222222222222222222222222222222222222222222222</p> <p>3ewrw Van der Sar's electricity and electricity fee of the third party in Shandong Province</p> <p>11111111111111111111111111111111111111111111111111111111111111111</p> <p>22222222222222222222222222222222222222222222222222222222222222</p> <p>3ewrw Van der Sar's electricity and electricity fee of the third party in Shandong Province</p> <p>11111111111111111111111111111111111111111111111111111111111111111</p> <p>22222222222222222222222222222222222222222222222222222222222222</p> <p>3ewrw Van der Sar's electricity and electricity fee of the third party in Shandong Province</p> <p>11111111111111111111111111111111111111111111111111111111111111111</p> <p>22222222222222222222222222222222222222222222222222222222222222</p> <p>3ewrw Van der Sar's electricity and electricity fee of the third party in Shandong Province</p> <p>11111111111111111111111111111111111111111111111111111111111111111</p> <p>22222222222222222222222222222222222222222222222222222222222222</p> <p>3ewrw Van der Sar's electricity and electricity fee of the third party in Shandong Province</p> <p>1111111111111111111111111111111111111111111111111111111111111111</p> <p>22222222222222222222222222222222222222222222222222222222222222</p> <p>3ewrw Van der Sar's electricity and electricity fee of the third party in Shandong Province</p> <p>1111111111111111111111111111111111111111111111111111111111111111</p> <p>22222222222222222222222222222222222222222222222222222222222222</p> <p>3ewrw Van der Sar's electricity and electricity fee of the third party in Shandong Province</p> <p>1111111111111111111111111111111111111111111111111111111111111111</p> <p>22222222222222222222222222222222222222222222222222222222222222</p> <p>3ewrw Van der Sar's electricity and electricity fee of the third party in Shandong Province</p> <img data-src="./img/7ff513a853b6d50887606dc436b1ddff.jpeg" alt=""> <img data-src="./img/8a728780b5ddd5672eb5bf8a4ce23c86.jpeg" alt=""> <img data-src="./img/ec6c60c8c5de6d7fa899807cfa8d46f1.jpeg" alt=""> <img data-src="./img/7ff513a853b6d50887606dc436b1ddff.jpeg" alt=""> <img data-src="./img/8a728780b5ddd5672eb5bf8a4ce23c86.jpeg" alt=""> <img data-src="./img/ec6c60c8c5de6d7fa899807cfa8d46f1.jpeg" alt=""> <p>22222222222222222222222222222222222222222222222222222222222222</p> <p>3ewrw Van der Sar's electricity and electricity fee of the third party in Shandong Province</p> <p>1111111111111111111111111111111111111111111111111111111111111111</p> <p>22222222222222222222222222222222222222222222222222222222222222</p> <p>3ewrw Van der Sar's electricity and electricity fee of the third party in Shandong Province</p> <p>1111111111111111111111111111111111111111111111111111111111111111</p> <p>22222222222222222222222222222222222222222222222222222222222222</p> <p>3ewrw Van der Sar's electricity and electricity fee of the third party in Shandong Province</p> <p>1111111111111111111111111111111111111111111111111111111111111111</p> <p>22222222222222222222222222222222222222222222222222222222222222</p> </div> </body> <script> let imgs = document.querySelectorAll('img') let observer=new IntersectionObserver(callBack) imgs.forEach(imgItem=>{ // Watch node, trigger callback function in new IntersectionObserver (callBack) observer.observe(imgItem) }) // IntersectionObserver passes in a parameter to the callback function function callBack(observerArray){ // observerArray: A collection of instances and observational states for each observed element object observerArray.forEach(item=>{ // item: Instance and observation state information of the observed element object // isIntersecting: Is it observed if(item.isIntersecting){ // item.target: Observed instance let imgDom=item.target imgDom.setAttribute('src', imgDom.getAttribute('data-src')) // Cancel observation observed observer.unobserve(imgDom) } console.log(item); }) } </script> </html>
(LEARN FROM Technical Egg Teacher)