Loading image delayed display after loaded

2.8k views Asked by At

So I have this html / css / jQuery / js code that toghether shows a VERY large image in width. The base element should be invisible untill the image is loaded and set. Then the base element is made visible by a small fade.

However the behaviour is a little different. Once the image is being loaded i can see the small text fading in and it takes a few seconds before then the image just pops up in once (not loading style like from top to bottom appearing)

This is the simplified code i use:

<script>
    $(function() {

        $("#base").hide();
        var baseHeight = $(window).height();
        var backLayerSRC = $('#img').attr('data-src');
        $('#base').height(baseHeight);

        var img = new Image();
        var imgWidth, imgHeight;

        img.onload = function() {
            imgHeight = this.height;
            imgWidth = this.width;

            var factor = 1 * baseHeight / imgHeight;
            totalWidth = Math.round(factor * imgWidth);

            currentWidth = totalWidth;
            $('#base').width(totalWidth);
            $('#img').attr('src', backLayerSRC);
            $('#img').height(baseHeight);

            $('#base').fadeIn(500);



        };

        img.src = backLayerSRC;

    });
</script>

<style>
    #base {
        position:absolute;
        left:0px;
        height:100%;
    }

    #base #img {
        position:absolute;
        left:0px;
        top:0px;
    }
</style>

<div id='base'>
    some tekst
    <img src='' id='img' data-src='path_to_very_large/image.png' />
</div>

Now, how could it be that it just doesn't fade in WITH the image?

Here is an example WITH the image, please check so it becomse clear what i mean http://jsfiddle.net/uz8mvtap/3

4

There are 4 answers

1
devtech On BEST ANSWER

It might depend on the time the browser needs to render the image after the script loaded it.

I played a little with your fiddle and came up with this:

$(function() {

    $("#base").css({opacity: 0});
    var baseHeight = $(window).height();
    var backLayerSRC = $('#img').attr('data-src');
    $('#base').height(baseHeight);

    var img = new Image();
    var imgWidth, imgHeight;

    img.onload = function() {
        imgHeight = this.height;
        imgWidth = this.width;

        var factor = 1 * baseHeight / imgHeight;
        totalWidth = Math.round(factor * imgWidth);

        currentWidth = totalWidth;
        $('#base').width(totalWidth);
        $('#img').attr('src', backLayerSRC);
        $('#img').height(baseHeight);

        $('#base').delay(1000).animate({opacity: 1.0},500);



    };

    img.src = backLayerSRC;

});

Basically using opacity for such a purpose is better because #base continues to occupy the same space, not disrupting the page. And the delay is for the browser, I figured for a big image it takes time to render, so let's give it it.

4
importantaccount1 On

Here is the working example of your code I have created:

https://codebrace.com/editor/b16cabfee

Your baseHeight variable is undefined. May be you should change

$('#base').height(baseHeight);

to

var baseHeight = $('#base').height();

Update:

I have updated the solution. I this solution I have wrapped div around both the text and image. Div wrapped around image is set to position:relative; to keep the image(set to absolute position) from covering the text.

https://codebrace.com/editor/b16f33afb

0
Thomas J. On

You could do that.

$('<img />').load( function(){
  console.log('loaded');
}).attr('src', imgUrl);

After it loads, it summons a callback, use that callback to do custom function. Let me know how it goes.

or, by the way. You could enter image width and image height into custom var, and compare them on the load, once it reaches your wanted width and height, fade it in.

4
Gary Thomas On

You seem to be slightly misinterpreting the timeline of your code:

  1. Page loads, (text is visible on screen)
  2. jQuery kicks in, hides #base (text is not visible on screen)
  3. jQuery fades in #base (text is visible on screen again)

This is why you are briefly seeing the text before the image loads - because it is not initially hidden.

Add:

display: none;

To your #base style, add keep the rest of your code the same.


Also I've created an alternative JavaScript solution after you have added the above CSS:

$(function() {
    const base = $("#base"),
        img = $("#img"),
        backLayerSRC = img.attr('data-src'),
        baseHeight = $('#base').height();

    img.attr('src', backLayerSRC);

    img.one("load", () => {
        img.height(baseHeight).promise().done(() => { base.fadeIn(2500); });
    });
});