In the past, it was very difficult to determine if an element was currently visible in the viewing area, or to see if the user was reading this content. To develop the website and get the data above to handle some useful functions to increase user experience and speed up the site. Today we have the same potential of the Intersection Observer API
What is the Intersection Observer API?
According to MDN
The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document’s viewport.
The Intersection Observer API provides a way to observe asynchronously observing changes in the interface with ancestor elements or with top-level document’s viewport.
(viewport: is a frame, maybe a polygonal area (usually a rectangle) on the screen that you are seen in. In a web browser, it refers to the document that the user is seeing , what appears in the application window (or on the screen if displayed in full screen). The parts outside the viewport are things you don’t see until you scroll to it.
Features are applicable
- Lazy-loading images or other information when the page is scrolling.
- Perform an “infinite scrolling” web page, where more and more information is downloaded and displayed as you scroll so users don’t have to flip through pages.
- Report the visibility of the ad to calculate ad revenue.
- The decision whether or not to perform tasks or animations is based on whether the user sees it or not.
- etc …….
Using
1 2 3 4 5 6 7 8 9 10 | var el = document.getElementById('#el'); var observer = new IntersectionObserver(function (entries) { entries.forEach(entry => { // TO DO }); }, options); observer.observe(el) else document.querySelector('#warning').style.display = 'block'; |
The examples
first . Lazyloading
In this example, we will save the image in data-src
1 2 | <img src="600px-PlaceholderLC.png" data-src="https://images.unsplash.com/photo-1504272017915-32d1bd315a59?fit=crop&w=600&q=80"> |
and load the image from data-src into src when scrolling to the image
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | if(!!window.IntersectionObserver){ let observer = new IntersectionObserver((entries, observer) => { // entries : Danh sách các đối tượng chúng ta theo dỏi entries.forEach(entry => { // Kiểm tra ảnh của chúng ta có trong vùng nhìn thấy không if(entry.isIntersecting){ /* Lấy dử liệu từ data-src mà chúng ta đã gán trước đó sau đó gàn vào thuộc tính src của ảnh , lúc này thì ảnh mới bắt đầu tải về * / entry.target.src = entry.target.dataset.src; observer.unobserve(entry.target); } }); }, {rootMargin: "0px 0px -200px 0px"}); document.querySelectorAll('img').forEach(img => { observer.observe(img) }); } else document.querySelector('#warning').style.display = 'block'; |
Here we can see a provided attribute:
1 2 | rootMargin: "0px 0px -200px 0px" |
This is a property that can temporarily expand or narrow the scope of the element we are following. In the example above we can see, the image load is executed when we scoll away from the position. Current image is 200px. If we do not use this property, the load will be executed as soon as the location of the image goes into the viewport. They can be used with values similar to the CSS border properties, for example, “10px 20px 30px 40px” (top, right, bottom, left).
Here I will give you another useful attribute
1 2 3 4 5 6 | var observer = new IntersectionObserver(function (entries) { entries.forEach(entry => { // TO DO }); }, {threshold: 1.0}); |
threshold : indicates the percentage of the component’s visibility to be performed. If you only want to detect when visibility exceeds 50%, you can use the value 0.5.
2 . Infinite Scroll
HTML section
1 2 3 4 5 6 7 | <div id="root"> <h1>Infinite Scroll with Intersection Observer API</h1> <p>Try to scroll me!</p> <div id="list"></div> <div id="list-end"></div> </div> |
Part Js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | // Interception Handler const callback = (entries, observer) => { for (const entry of entries) { console.log(entry); // Load more articles; if (entry.isIntersecting) { if (articleCount < 10) { loadArticles(); } else { observer.unobserve(listEnd); } } } } // Observe the end of the list const observer = new IntersectionObserver(callback, { threshold: 0, }); observer.observe(listEnd); |
Compare Intersection Observer and EventListener Scroll
According to many articles comparing the Intersection Observer for a better feature, its power is in its flexibility and integrated functions. You can also see some of the comparison articles here:
https://itnext.io/1v1-scroll-listener-vs-intersection-observers-469a26ab9eb6
https://medium.com/@cristinallamas/intersection-observer-vs-eventlistener-scroll-90aed9dc0e62
Can I Use
Conclude
The Intersection Observer provides outstanding features, making it easier to handle complex functions and improve performance. Replaces EventListener Scroll in handling many tasks, such as lazy load images, infinite scroll, …
Refer
https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
https://css-tricks.com/a-few-functional-uses-for-intersection-observer-to-know-when-an-element-is-in-view/
https://www.smashingmagazine.com/2018/01/deferring-lazy-loading-intersection-observer-api/
https://medium.com/better-programming/understanding-intersection-observer-api-in-javascript-bb1bf04b8081