0

I have a slider with a html like this

<div id="bilder">                 | height: 70vh;
  <div id="pappediv">             | height: 100%;
    <div id="slider">             | height: 70%;
      <div id="imagecontainer">   | height: 100%;
        <p>                       | height: 100%;
          <img>                   | height: 100%;
          <img>                   | height: 100%; 
          <iframe>                | height: 100%;

(about 12 images and one iframe. all elements are closed, not shown here for brevety.)

I need to fill an array with the rendered widths of all images. To this i use the following javascript:

$(document).ready(function(){

var elements = $('#imagecontainer>p').children();
var widths = [];
elements.each(function() {
    widths.push(this.width);
});
console.log(widths);
});

The code works and delivers width values for each image. This also means that the code is run after the photos are available.

the problem is, that the width values returned are not the rendered width, which is viewport-height dependent but always the same "ideal" width value intrinsic to the images.

instead of "this.width" I tried a couple of other properties:

outerWidth - the images have a padding, which is then included 
offsetWidth - same as outerWidth
clientWidth - same

     elements.each(function() {
              rect = this.getBoundingClientRect();
              widths.push(rect.width);
     });

yields same

elements.each(function() {
        var thiswidth = getComputedStyle(this).width;
        widths.push(thiswidth);
    });

yields widths as a string but also the wrong values.

also, I used

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

instead of

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

without success.

Maybe it's a timing problem? Any hints are welcome.

2 Answers 2

0

Using

$(window).on("load", function( ){ ... })

is what you need in order to wait for the images to be loaded.

See the code snippet below. Note I based the css on the height info that you included in your html. The intrinsic widths of the images are 200 and 210.

$(window).on("load", function(){
  var elements = $('#imagecontainer>p').children();
  var widths = [];

  elements.each(function() {
    widths.push(this.width);
  });

  console.log(widths);
});
#bilder {
  height: 70vh;
  background-color: red;
  padding: 20px;
}
div {
  height: 100%;
  border: 2px solid black;
}
#slider {
  height: 70%;
  background-color: green;
  padding: 20px;
}
p {
  height: 100%;
  border: 2px solid yellow;
}
img {
  height: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div id="bilder">                 | height: 70vh;
  <div id="pappediv">             | height: 100%;
    <div id="slider">             | height: 70%;
      <div id="imagecontainer">   | height: 100%;
        <p>                       | height: 100%;
          <img src="https://placebear.com/g/200/300">                | height: 100%;
          <img src="https://picsum.photos/210/300">                  | height: 100%;
          <iframe>
          </iframe>
        </p>
      </div>  <!-- END imagecontainer -->
    </div>  <!-- END slider -->
  </div>  <!-- END pappediv -->
</div>  <!-- END bilder -->

2
  • Many thanks for the great and labourious answer! I did use "$(window).on("load", function( ){ ... })" though, as mentioned, without success. I actually think it's a timing issue, see below. Commented Jun 14 at 18:13
  • Can you show your code using .on("load"...) where it doesn't work? It is spec'ed to work and as you can see if you ran my code snippet, it is indeed working. Commented Jun 14 at 19:09
0

I found out, that the only thing working was to make the script wait a little before evaluating the width property, using setTimeout(). Apparently, the javascript does evaluate things after loading but before complete rendering of the page. I wonder whether there is a command like

 $(window).on("render", ...)

So the following code worked for me:

elements = $('#imagecontainer>p').children();
widths = [];

setTimeout(function() {
    elements.each(function() {
        widths.push(parseInt(this.width));
    });
    /* do stuff here */
},200);

Not the answer you're looking for? Browse other questions tagged or ask your own question.