Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

485
Views
Why getComputedStyle() is not getting actual width and height is there any callback or event exists

I'm in such a situation where i need to wait till the image gets loaded once the image gets loaded i need to gets its computed height so that i can set the yellow color selector accordingly.

Question: based on computed height of image i'm setting yellow color selector. it works with setTimeout() randomly but i don't want such approach.

let images = ['https://via.placeholder.com/150','https://via.placeholder.com/110/0000FF/808080%20?Text=Digital.com','https://via.placeholder.com/80/0000FF/808080%20?Text=Digital.com'];

let image = `<img src="${images[Math.floor(Math.random()*images.length)]}"/>`


document.getElementById('content').innerHTML = `<div class="box">${image}</div>`;

//actual code

let height = window.getComputedStyle(document.querySelector('.box'), null).getPropertyValue('height');

let imageWidth = window.getComputedStyle(document.querySelector('.box img'), null).getPropertyValue('width');

console.log('height',height,'width',imageWidth);

wrapImage = `<div style="width:calc(${imageWidth} + 10px);height:calc(${height} + 10px);position:absolute;left:0;top:0;border:1px solid yellow;"></div>`;

document.querySelector('.box').insertAdjacentHTML('beforeend',wrapImage);
.box{
   width:100%;
   height:auto;
   border:1px solid red;
   position:relative;
}
<div id="content">

</div>

with setTimeout it works but i don't want such approach,i want callback or some event once element is ready

let images = ['https://via.placeholder.com/150','https://via.placeholder.com/110/0000FF/808080%20?Text=Digital.com','https://via.placeholder.com/80/0000FF/808080%20?Text=Digital.com'];

let image = `<img src="${images[Math.floor(Math.random()*images.length)]}"/>`


document.getElementById('content').innerHTML = `<div class="box">${image}</div>`;

//actual code

setTimeout(() => {
   let height = window.getComputedStyle(document.querySelector('.box'), null).getPropertyValue('height');

let imageWidth = window.getComputedStyle(document.querySelector('.box img'), null).getPropertyValue('width');

console.log('height',height,'width',imageWidth);

wrapImage = `<div class="select" style="width:calc(${imageWidth} + 10px);height:${height};position:absolute;left:0;top:0;border:1px solid yellow;"></div>`;

document.querySelector('.box').insertAdjacentHTML('beforeend',wrapImage);

document.querySelector('.select').height = document.querySelector('.select').height + 10;

console.log('after computed height and added 10px',window.getComputedStyle(document.querySelector('.box'), null).getPropertyValue('height'));

},700);
.box{
   width:100%;
   height:auto;
   border:1px solid red;
   position:relative;
}
<div id="content">

</div>

Please help me thanks in advance !!!

over 4 years ago · Santiago Trujillo
6 answers
Answer question

0

You could consider adding the 'load' event listener as a callback for image loading. Please check the example:

const image = document.getElementById('image');
const handler = () => {
  alert(image.height);
};

image.addEventListener('load', handler);
<img src="https://image.shutterstock.com/z/stock-vector-sample-stamp-grunge-texture-vector-illustration-1389188336.jpg" id="image" />

over 4 years ago · Santiago Trujillo Report

0

The image hasn't finished loading when you retrieved the height and width. To solve this, you'll need to wait for the images to load first, then get their height and width.

Listen for the window load event, which will fire when all resources (including images) have loaded completely:

let images = ['https://via.placeholder.com/150', 'https://via.placeholder.com/110/0000FF/808080%20?Text=Digital.com', 'https://via.placeholder.com/80/0000FF/808080%20?Text=Digital.com'];

let image = `<img src="${images[Math.floor(Math.random()*images.length)]}"/>`


document.getElementById('content').innerHTML = `<div class="box">${image}</div>`;

//actual code

window.addEventListener('load', function() {
  let height = window.getComputedStyle(document.querySelector('.box'), null).getPropertyValue('height');

  let imageWidth = window.getComputedStyle(document.querySelector('.box img'), null).getPropertyValue('width');

  console.log('height', height, 'width', imageWidth);

  wrapImage = `<div class="select" style="width:calc(${imageWidth} + 10px);height:${height};position:absolute;left:0;top:0;border:1px solid yellow;"></div>`;

  document.querySelector('.box').insertAdjacentHTML('beforeend', wrapImage);

  document.querySelector('.select').height = document.querySelector('.select').height + 10;

  console.log('after computed height and added 10px', window.getComputedStyle(document.querySelector('.box'), null).getPropertyValue('height'));

});
.box {
  width: 100%;
  height: auto;
  border: 1px solid red;
  position: relative;
}
<div id="content">

</div>

over 4 years ago · Santiago Trujillo Report

0

To indicate selection you can use CSS outline property. That way you won't have to manage selection dimensions yourself.
Following is demo code. As you want to do it over multiple images, I've added 3 images. And you can select multiple images.

function changeImages() {
  var images = document.getElementsByTagName('img');
  for (var i = 0; i < images.length; i++) {
    images[i].src = "https://via.placeholder.com/" + Math.floor(Math.random() * 50 + 50).toString() + "/0a0a0a/ffffff";
  }
}

function setClickEvents() {
  var images = document.getElementsByTagName('img');
  for (var i = 0; i < images.length; i++) {

    images[i].addEventListener("click", function(event) {
      event.target.classList.toggle("selected");
    });;

  }
}

function init() {
  document.getElementById('content').innerHTML = `<div id="box"></div>`;

  var box = document.getElementById('box');
  var img = document.createElement("img");
  img.classList.add("selected");
  box.appendChild(img);
  box.appendChild(document.createElement("img"));
  box.appendChild(document.createElement("img"));

  setClickEvents();
  changeImages();
}
#content {
  padding: 15px;
  margin: 10px;
}

#box {
  width: 100%;
  height: 120px;
  border: 1px dotted red;
  position: relative;
}

img {
  margin: 15px;
}


/* use this class for marking selected elements */
.selected {
  outline: thick double #f7d205;
  outline-offset: 7px;
}
<!DOCTYPE html>
<html lang="en">

<body onload="init()">
  <button onclick="changeImages()">Change Images</button>

  <div id="content"></div>
</body>

</html>

Click on image to toggle selection.

over 4 years ago · Santiago Trujillo Report

0

If you want more flexibility then you can use Resize Observer. With this when you change src attribute of image tag you'll able to change selection size.

const imageObserver = new ResizeObserver(function(entries) {
  for (let entry of entries) {
    var img = entry.target;
    let height = img.height + 10;
    let width = img.width + 10;

    console.log('Added 10px. height:', height, ' width:', width);

    wrapImage = `<div class="select" style="width:${width}px;height:${height}px;position:absolute;left:0;top:0;border:1px solid #f7d205;"></div>`;
    document.querySelector('.box').insertAdjacentHTML('beforeend', wrapImage);
  }
});

function init() {
  document.getElementById('content').innerHTML = `<div id="box" class="box"></div>`;

  var box = document.getElementById('box');
  var img = document.createElement("img");
  img.src = "https://via.placeholder.com/" + Math.floor(Math.random() * 50 + 80).toString() + "/0a0a0a/ffffff";
  box.appendChild(img);
  imageObserver.observe(img);
}
<!DOCTYPE html>
<html lang="en">
<style>
  #box {
    width: 100%;
    border: 1px dotted red;
    position: relative;
  }
</style>

<body onload="init()">
  <div id="content"></div>
</body>

</html>


Note: Using same ResizeObserver you can observe multiple images:

var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
  imageObserver.observe(images[i]);
}

Edit: As requested, demonstrating observing img resize from parent div element. Here the image is wrapped in div #box. On resize img dispatches a custom event and parent handles it.

function handleChildResize(event) {
  console.log('parent: got it! handling it.. ')
  var img = event.data;
  let height = img.offsetHeight + 10;
  let width = img.offsetWidth + 10;

  console.log('Added 10px. height:', height, ' width:', width);

  wrapImage = `<div class="select" style="width:${width}px;height:${height}px;position:absolute;left:0;top:0;border:2px solid #f7d205;"></div>`;
  if (document.querySelector('.box > .select')) {
    document.querySelector('.box > .select').remove();
  }
  document.querySelector('.box').insertAdjacentHTML('beforeend', wrapImage);
  event.stopPropagation();
}

const imgObserver = new ResizeObserver(function(entries) {
  for (let entry of entries) {
    var img = entry.target;
    var event = new Event('childResized');
    event.data = img;
    console.log("img: i am resized. Raising an event.");
    img.dispatchEvent(event);
  }
});

function init() {
  var box = document.getElementById('box');
  box.addEventListener('load', (event) => {
    console.log('The page has fully loaded');
  });
  var img = document.createElement("img");
  img.src = "https://via.placeholder.com/" + Math.floor(Math.random() * 50 + 80).toString() + "/0a0a0a/ffffff";
  box.appendChild(img);
  imgObserver.observe(img);
  box.addEventListener('childResized', handleChildResize, true);
}
<!DOCTYPE html>
<html>
<head>
  <style>
    #box {
      width: 100%;
      padding: 10px;
      border: 1px solid red;
      position: relative;
    }
  </style>
</head>

<body onload="init()">
  <div id="content">
    <div id="box" class="box"></div>
  </div>
</body>

</html>

over 4 years ago · Santiago Trujillo Report

0

I see that you are creating your imgNode on a fly using ternary which means you do not have it pre-created in your HTML. So for that, you can use the solution as below by creating an Image constructor.

const images = [
  "https://via.placeholder.com/150",
  "https://via.placeholder.com/110/0000FF/808080%20?Text=Digital.com",
  "https://via.placeholder.com/80/0000FF/808080%20?Text=Digital.com"
];

const img = new Image();

img.addEventListener("load", (ev) => {
  console.log(ev);

  document.getElementById(
    "content"
  ).innerHTML = `<div class="box">${ev.target}</div>`;

  const height = window
    .getComputedStyle(document.querySelector(".box"), null)
    .getPropertyValue("height");

  const imageWidth = window
    .getComputedStyle(document.querySelector(".box img"), null)
    .getPropertyValue("width");

  console.log("height", height, "width", imageWidth);

  const wrapImage = `<div style="width:calc(${imageWidth} + 10px);height:calc(${height} + 10px);position:absolute;left:0;top:0;border:1px solid yellow;"></div>`;

  document.querySelector(".box").insertAdjacentHTML("beforeend", wrapImage);
});

img.src = `${images[Math.floor(Math.random() * images.length)]}`;
over 4 years ago · Santiago Trujillo Report

0

I see that you want to compute the final value of the get computed style you see. The thing is that the getComputedStyle doesn't get updated. So just make a function to do it!

let images = ['https://via.placeholder.com/150','https://via.placeholder.com/110/0000FF/808080%20?Text=Digital.com','https://via.placeholder.com/80/0000FF/808080%20?Text=Digital.com'];'

let image = `<img src="${images[Math.floor(Math.random()*images.length)]}"/>`


document.getElementById('content').innerHTML = `<div class="box">${image}</div>`;

//actual code

setTimeout(() => {
   let height;
   let imageWidth;
   function calculateHeightAndWidth() {
        
height = window.getComputedStyle(document.querySelector('.box'), null).getPropertyValue('height');

imageWidth = window.getComputedStyle(document.querySelector('.box img'), null).getPropertyValue('width');

   }
   calculateHeightAndWidth()


console.log('height',height,'width',imageWidth);

wrapImage = `<div class="select" style="width:calc(${imageWidth} + 10px);height:${height};position:absolute;left:0;top:0;border:1px solid yellow;"></div>`;

document.querySelector('.box').insertAdjacentHTML('beforeend',wrapImage);

document.querySelector('.select').height = document.querySelector('.select').height + 10;

calculateHeightAndWidth()
console.log('after computed height and added 10px',window.getComputedStyle(document.querySelector('.box'), null).getPropertyValue('height'));

},700);
.box{
   width:100%;
   height:auto;
   border:1px solid red;
   position:relative;
}
<div id="content">

</div>

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!