0

I'm new to JavaScript and pulling my hair out over this...

A demo of the problem is here: http://codepen.io/sol_b/pen/PzgdWy

And this is the script:

var sections = function() {
  $('.image').each(function() {
    var $this = $(this),
        x = $this.find('img').width()
    $this.width(x);
  });
};

$(document).ready(function() { 
  sections();
 });

$(window).resize(function() {
  sections();
})

The width of an image is calculated and assigned to the image's container. The idea is that the row of images will always maintain their aspect ratio, without gaps between the containers.

The problem is the code fails about 50% of the time and the images just squish together. Resizing the window fixes it so I think it's something to do with the loading sequence.

I've tried using window.onload and img.onload instead of document.ready, and these didn't solve it. Have I missed something in my script?

4
  • 2
    From the docs: "In cases where code relies on loaded assets (for example, if the dimensions of an image are required), the code should be placed in a handler for the load event instead." Commented Aug 23, 2016 at 12:22
  • Documentation states "In cases where code relies on loaded assets (for example, if the dimensions of an image are required), the code should be placed in a handler for the load event instead." Commented Aug 23, 2016 at 12:27
  • @JuanMendes please remove the duplicate here. This is not the question! It is not about all images. Commented Aug 23, 2016 at 12:33
  • There's an example on how to wait for specific images stackoverflow.com/questions/15134468/… Just be careful that the images may be cached so the load event may have already fired by the time you register a listener Commented Aug 23, 2016 at 12:36

5 Answers 5

3

Use load on the images and count till all are loaded, then execute your function.

var images $('.image');
var amount = images.length;

images.on('load', function() {
    if( --amount == 0 ) {
        sections();
    }
});

To prevent cached images to be executed from the listener, you could trigger them manually (even on window.load). This lines will fire the event for cached elements:

images.each(function() {
    $(this).complete && $(this).trigger('load');
});
Sign up to request clarification or add additional context in comments.

8 Comments

That's just overcomplicating it when you could just use the window load event
This is only needed if the images are created dynamically. Note that the load event may not fire if the image is cached. The load event on the window already waits for all images
@JuanMendes This is only needed if the images are created dynamically What do you mean?
@A.Wolff Using the windows load event waits for all resources to load. Using the images own load event makes sure your code is ran when the images load... which is exactly what you want.
@A.Wolff Scripts can be loaded async (and should be, unless they require being ran sync), and stylesheets and subframes can take longer to fetch than images (especially if the images are cached).
|
2

Use instead:

$(window).on('load resize', sections);

1 Comment

Yes this seems to be the best approach. Surprised I didn't think of this +1
0

Try using 'on load' event handler instead of $(document).ready:

$(window).on('load', function() { 
  sections();
});

instead of:

$(document).ready(function() { 
  sections();
});


Or you can use:

$(window).on('load resize', function() { 
  sections();
});

To handle both events :)

Comments

-1

I believe what you're looking for is the timeout() function.

If my understanding is correct you can call window.timeout([function to call], [time in ms] and the function to call will execute that many ms AFTER the code is executed. It will not wait like a sleep().

Comments

-1
setTimeout(
    function(){
        console.log("this line will be logged with 1000ms delay");
    },1000
)

W3C documentation

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.