Peter
Peter

Reputation: 1916

Dynamically replace image src after the page loaded and the image is completely downloaded

Am trying to create a simple lazy image load to replace default image with main item image after page has loaded and image is fully downloaded. But am getting and error using below jquery code.

HTML Example

<img src="default.png" data-src="image-1.png" class="productImage"/>
<img src="default.png" data-src="image-2.png" class="productImage"/>
<img src="default.png" data-src="image-3.png" class="productImage"/>
<img src="default.png" data-src="image-4.png" class="productImage"/>

Jquery Example

$(function(){
    $('img.productImage').each(function(){
       var this_image = this;
       var src = $(this_image).attr('src');
       var lsrc = $(this_image).attr('data-src');
        if(lsrc.length > 0){
            var img = new Image();
            img.src = lsrc;
            $(img).load(function() {
                this_image.src = this.src;
            });
        }else{
            this_image.src = src;
        }
    });
});

The above script give this error TypeError: e.indexOf is not a function[Learn More] jquery-3.2.1.min.js:2:82466.

I have also tried to use below code and it worked but am not very sure that it does wait for the image to download before replacing the src, because it always replace one page load.

$(function(){
    $('img.productImage').each(function(){
       var this_image = this;
       var src = $(this_image).attr('src');
       var lsrc = $(this_image).attr('data-src');
            if(lsrc.length > 0){
                this_image.src = lsrc;
            }else{
                this_image.src = src;
            }

    });
});

Upvotes: 1

Views: 2229

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074048

load is not a shortcut for .on("load", it does something completely different (loads HTML from the server and put it in the element). Separately, always hook the load event before setting src, not after, to avoid race conditions.

var img = new Image();
$(img).on("load", function() {
    this_image.src = this.src;
});
img.src = lsrc;

Using on instead of load solves the weird url.indexOf (e.indexOf in the minified version) error:

$(function(){
    $('img.productImage').each(function(){
       var this_image = this;
       var src = $(this_image).attr('src');
       var lsrc = $(this_image).attr('data-src');
       if(lsrc.length > 0){
            var img = new Image();
            $(img).on("load", function() {
                this_image.src = this.src;
            });
            img.src = lsrc;
        }else{
            this_image.src = src;
        }
    });
});
<img src="http://via.placeholder.com/100x100?text=p" data-src="http://via.placeholder.com/100x100/08f/000?text=1" class="productImage"/>
<img src="http://via.placeholder.com/100x100?text=p" data-src="http://via.placeholder.com/100x100/08f/000?text=2" class="productImage"/>
<img src="http://via.placeholder.com/100x100?text=p" data-src="http://via.placeholder.com/100x100/08f/000?text=3" class="productImage"/>
<img src="http://via.placeholder.com/100x100?text=p" data-src="http://via.placeholder.com/100x100/08f/000?text=4" class="productImage"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

Upvotes: 1

Related Questions