Personal Packaging common methods toolkit: github.com/lihai-boop/…
Articles included: github.com/lihai-boop/…
1. Calculation of rolling distance
ScrollTop offsetTop, clientHeight native API for pixel distance calculation
OffsetTop: Gets the distance between the current element and the top inner margin of its parent element
ScrollTop: The height beyond which the current element is scrolled
ClientHeight: The visible height of the current element
“Soul Painter” drawing
Img element offsetTop – Parent element scrollTop< parent element clientHeight, that is, img has been rolled into the parent visible area
#view {
width: 300px;
height: 500px;
margin: 30px auto;
overflow-y: auto;
}
.parent {
height: 1000px;
}
img {
margin-top: 800px;
}
Copy the code
<div id="view">
<div class="parent">
<img alt="..." loading="lazy" class="img"
data-src="https://tse1-mm.cn.bing.net/th?id=OIP-C.FaG6dzohGs3q45-DwsEyQQHaEK&w=165&h=100&c=8&rs=1&qlt=90&o=6&pid=3.1&rm=2">
</div>
</div>
Copy the code
let view = document.getElementById('view');
let img = document.getElementsByClassName('img') [0];
view.onscroll = function () {
let sh = this.clientHeight;
let st = this.scrollTop;
let ch = img.offsetTop;
ch - st < sh && (img.src = img.dataset.src)
}
Copy the code
When the user frequently scrolls the mouse, the OnScroll event will be triggered for several times to calculate the rolling distance, which is meaningless to consume performance. Therefore, it is necessary to control the number of times the function is executed to reduce performance consumption and take anti-shake treatment for the rolling event
In order to reduce the repeated writing of the anti – shake function during development, it has been sealed in @lihai-js/tool, out of the box
@ lihai – js/tool address github.com/lihai-boop/…
let img = document.getElementsByClassName('img') [0];
let view = document.getElementById('view');
function debounce (fn, wait = 1000, immediate = false) {
const self = this
immediate && fn.call(this)
return function () {
self.debounceTime && clearTimeout(self.debounceTime)
self.debounceTime = setTimeout(() = > {
fn.apply(this.arguments)
}, wait)
}
}
view.onscroll =debounce(function () {
let sh = view.clientHeight;
let st = view.scrollTop;
let ch = img.offsetTop;
ch - st < sh && (img.src = img.dataset.src)
})
Copy the code
2. getBoundingClientReat
Method to calculate
Element. GetBoundingClientReat () method returns the Element size and its position relative to the viewport.
This method returns a DOMRect object containing eight attributes: left, top, right, bottom, x, y, width, and height. Properties other than width and height are evaluated relative to the top left corner of the view window.
Element. GetBoundingClientRect () – Web API interface reference | MDN (mozilla.org)
For the code example of the scroll distance enumeration, the visible window is the browser window, and the imgDOM object uses getBoundingClientReat() to get the top, which is the pixel distance from the top left corner of the browser window to the top left corner of the IMG tag
Using the above points, when the value of top is less than the height of the browser window, the IMG has been scrolled in the viewable area and is loaded
#view {
width: 300px;
height: 500px;
margin: 30px auto;
overflow-y: auto;
}
.parent {
height: 1000px;
}
img {
margin-top: 800px;
margin-bottom: 30px;
}
Copy the code
<div id="view">
<img alt="..." class="img" data-src="https://p.pstatp.com/origin/pgc-image/c206105e0c46482a85b69a67a59ce682" />
</div>
Copy the code
let img = document.getElementsByClassName('img') [0];
let view = document.getElementById('view');
// omit the anti-shake code
window.onscroll = debounce(() = > {
let clientHeigth = view.clientHeight;
let { top } = img.getBoundingClientRect();
top < clientHeigth && (img.src = img.dataset.src);
})
view.onscroll =debounce(function () {
let sh = view.clientHeight;
let { top } = img.getBoundingClientRect();
top<sh && (img.src = img.dataset.src)
})
Copy the code
3. IntersectionObserver
Listening to the
The principle of IntersectionObserverAPI is the same as that calculated by method 2. GetBoundingClientReat. According to the official opinion, images are lazy to load, and developers need to obtain top value, monitor rolling events and handle shaking, which makes a series of operations inconvenient and inconvenient. To simplify it, IntersectionObserver interface is officially provided.
IntersectionObserver(callback[, options])
When the listening element meets the requirement, the callback is triggered, which takes two arguments
How to use IntersectionObserver API – Ruanyifeng.com
let img = document.getElementsByClassName('img') [0];
let view = document.getElementById(view);
let ob = new IntersectionObserver(function (changes) {
changes.forEach(val= > {
let{ isIntersecting, target } = val; isIntersecting && (target.src = target.dataset.src); })}, {root: view,
threshold: [0]
})
ob.observe(img);
Copy the code
4.<img>
Tag attributesloading
Not recommended because of poor compatibility
Tag attribute loding, optional values:
Eager: Loads the image immediately
Lazy: Lazily loads an image until it approaches a calculated distance from the viewport, as defined by the browser
Details: developer.mozilla.org/zh-CN/docs/…
<div class="parent">
<img loading="lazy"
src="https://tse1-mm.cn.bing.net/th?id=OIP-C.FaG6dzohGs3q45-DwsEyQQHaEK&w=165&h=100&c=8&rs=1&qlt=90&o=6&pid=3.1&rm=2" alt="...">
</div>
Copy the code
The last
Look forward to fellow students give directions to supplement!
Think the article useful students point a wave of praise!