Image lazy loading

1. What is image scroll loading?
In layman's terms: when visiting a page, first replace the background image path of the img element or other elements with a path with a size of 1*1px (so that you only need to request it once), only when the image appears in the browser. Only when it is within the visible area of ​​​​the device, the true path of the picture is set, so that the picture is displayed. This is image lazy loading.
2. Why use this technology?
For example, there are many pictures in a page, such as Taobao, Jingdong homepage, etc. If you send so many requests as soon as you come up, the page loading will take a long time. If the js files are placed at the bottom of the document, it happens that the head of the page depends on This js file is not easy to handle. What's more terrible is that the server may be overwhelmed by sending 180 requests as soon as it comes up (and it's not just one or two people visiting this page).
So the advantages are obvious: not only can it reduce the pressure on the server, but also make the loaded page appear to the user faster (good user experience).
Three, how to achieve?
The key points are as follows:
1. If the img element in the page does not have the src attribute, the browser will not send a request to download the image (there is no request, and the performance will be improved). Once the image path is set through javascript, browse server will send the request. It means assigning on demand. If you don't want to see it, I won't show it to you. If you want to see it, I will show it to you.
2. How to get the real path, this is simple, and now the real path exists in the "data-url" element of the element "(This name is something you know and remember.) In the attribute, take it out when you want to use it, and then set it up;
3. Before starting the comparison, first understand some basic knowledge, such as how to get the size of an element , the scroll bar scrolling distance and the offset position distance; 
1) The size of the visible window on the screen:
Native method: window.innerHeight standard browser and IE9+ || document.documentElement.clientHeight standard browser and lower version IE standard mode ||document.body.clientHeight lower version promiscuous mode
jQuery method: $(window).height()
2 ) The distance between the top of the browser window and the top of the document, that is, the scrolling distance of the scroll bar:
Native method: window.pagYoffset——IE9+ and standard browsers|| document.documentElement.scrollTop Compatible with the standard mode of lower versions of ie||
document.body.scrollTop is compatible with promiscuous mode;
jQuery method: $(document).scrollTop();
3) Get the size of the element: corresponding to positions 5 and 6 in the figure; the jquery method on the left, the native method on the right
$(o). width() = o.style.width;
$(o).innerWidth() = o.style.width+o.style.padding;
$(o).outerWidth() = o.offsetWidth = o.style.width+ o.style.padding+o.style.border;
$(o).outerWidth(true) = o.style.width+o.style.padding+o.style.border+o.style.margin;
Note: To use the native style.xxx method to get attributes, the element must already have an inline style, such as <div style="...."></div>;
if it was originally defined through an external or internal style sheet css style, you must use o.currentStyle[xxx] || document.defaultView.getComputedStyle(0)[xxx] to get the style value
4) Get the position information of the element: corresponding to the position 7 and 8 in the figure
1) Relative to the returned element The distance from the top and left of the document document;
jQuery: The distance between the $(o).offset().top element and the top of the document, and the distance between the $(o).offset().left element and the left edge of the document
. Native: getoffsetTop() , there are specific instructions on the elevation, which are ignored here; by the
way, the offset distance of the returned element relative to the first positioned parent element, pay attention to the difference from the above offset;
jQuery: position() returns an object , $(o).position().left = style.left, $(o).position().top = style.top;
4. After knowing how to get the element size and offset distance, the next question is: How to judge that an element has entered or is about to enter the visible window area? Below is a picture to illustrate the problem.
1) The largest box outside is the size of the actual page, the light blue box in the middle represents the size of the parent element, and objects 1 to 8 represent the actual position of the element on the page; the horizontal direction is explained below!
2) The offset distance (offsetLeft) of the left border of object 8 relative to the left border of the page is greater than the distance of the right border of the parent element relative to the left border of the page, and the interpretable element is located outside the parent element at this time;
3) The left border of object 7 crosses the right border of the parent element. At this time, the offset distance (offsetLeft) of the left border of object 7 relative to the left border of the page is smaller than the distance of the right border of the parent element relative to the left border of the
page , so object 7 is Enter the parent element visible area;
4) At the position of object 6, the distance between the right border of object 5 and the left border of the page is greater than the distance between the left border of the parent element and the left border of the page;
5) At the position of object 5, the object The distance between the right border of 5 and the left border of the page is smaller than the distance between the left border of the parent element and the left border of the page; at this time, it can be judged that the element is outside the visible area of ​​the parent element;
6) Therefore, two conditions must be satisfied in the horizontal direction to explain The element is located in the visible area of ​​the parent element; in the same way, the vertical direction must also meet two conditions; see the source code below for details;
4. Extend to jquery plugin
Usage : $("selector").scrollLoad({ The parameter is in the code With description})
(function($) {
    $.fn.scrollLoading = function(options) {
        var defaults = {
            // attribute name stored in html tag;
            attr: "data-url",
            // parent element defaults to window
            container: window,
            callback: $.noop
        };
        // Regardless of whether there are parameters passed in, merge them first;
        var params = $.extend({}, defaults, options || {});
        // Convert the parent element to a jquery object;
        var container = $(params.container);
        // Create an array, then call the each method, Used to store data related to each dom object;
        params.cache = [];
        $(this).each(function() {
            // Take out the node type of each dom object in the jquery object, and take out the settings on each dom object The image path of
            var node = this.nodeName.toLowerCase(), url = $(this).attr(params["attr"]);
            //Reorganize, save the attributes on each dom object as an object;
            var data = {
                obj: $(this),
                tag: node,
                url: url
            };
            // add this object to an array;
            params.cache.push(data);
        });


        var callback = function(call) {
            if ($.isFunction(params.callback)) {
                params.callback.call(call);
            }
        };
        
        //Every time a scroll event is triggered, perform a function on each dom element and container element Position judgment, if the conditions are met, assign the path to this dom element!
        var loading = function() {
            // Get the height of the parent element
            var contHeight = container.outerHeight();
            var contWidth = container.outerWidth();


            // Get the distance of the parent element relative to the top of the document page, pay attention here , divided into the following two cases;
            if (container.get(0) === window) {
                // In the first case, the parent element is window, and the distance that the browser scroll bar has been scrolled is obtained; $(window) has no offset( ) method;
                var contop = $(window).scrollTop();
                var conleft = $(window).scrollLeft();
            } else {
                // In the second case, the parent element is a non-window element, get the scrolling distance of its scroll bar;
                var contop = container.offset().top;
                var conleft = container.offset().left;
            }


            $.each(params.cache, function(i, data) {
                var o = data.obj, tag = data.tag, url = data.url, post, posb, posl, posr;
                if (o) {
                    //The distance between the top of the object and the top of the document, if it is less than the distance between the bottom of the parent element and the top of the document, it means that the vertical direction has entered the visible area;
                    post = o.offset() .top - (contop + contHeight);
                    //The distance between the bottom of the object and the top of the document, if it is greater than the distance between the top of the parent element and the top of the document, it means that the vertical direction has entered the visible area;
                    posb = o.offset().top + o.height() - contop;


                    // same for horizontal;
                    posl = o.offset().left - (conleft + contWidth);
                    posr = o.offset(). left + o.width() - conleft;


                    // Only when the object is visible and these four conditions are met, the image path can be assigned to this object;
                    if ( o.is(':visible') && (post < 0 && posb > 0) && (posl < 0 && posr > 0) ) {
                        if (url) {
                            //in the browser window
                            if (tag === "img") {
                                //set the image src
                                callback (o.attr("src", url));
                            } else {
                                // Set the background url of elements other than img
                                callback(o.css("background-image", "url("+ url +")"));
                            }
                        } else {
                            // No address, directly trigger the callback
                            callback( o);
                        }
                        // After setting the image path for the object, clear the object in params.cache; when the object enters the visible area, it will not be set repeatedly;
                        data.obj = null;
                    }
                }
            }) ;
        }; //Execute         loading()
        after loading;         //Scroll to execute         container.bind("scroll", loading);     };




})(jQuery);

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324739228&siteId=291194637