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. getBoundingClientReatMethod 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. IntersectionObserverListening 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!