I'm appending the dynamically created image element to document.
var img = new Image();
img.src = 'test.jpg',
img.onload = function() {
var addedImg = container.appendChild(img);
console.log(img.width); //old width.
}
The problem here is the fact if I take image dimensions right after container.appendChild(img)
it returns the source file dimensions because the appendChild has not finished yet(not repainted?) and dimensions are not re-calculated.
var addedImg = container.appendChild(img);
console.log(img.width) //returns original width of the image
So, I'm wondering if it is possible to catch the load event for appendChild?
I know it is possible using setTimeout/setInterval
, but I guess there should be more elegant solution.
var addedImg = container.appendChild(img);
setTimeout(function() {
console.log(img.width); //return correct resolution after image dimensions were recalculated
}, 1000);
The problem with setTimeout/setInterval is the fact I don't know when element is finally appended and repainted. I have to run it on a loop.
I was trying to listen to DOMNodeInsertedIntoDocument
and DOMNodeInserted
events however it does not work.
img.addEventListener("DOMNodeInserted", onImageInserted, false);
img.addEventListener("DOMNodeInsertedIntoDocument", onImageInserted, false);
function onImageInserted(event) {
console.log(img.width); //still wrong width
}
However, it seems to run right after appendChild is fired.
Here is the fiddle so you can see what I'm talking about: /
Note: please don't advise to check the width of the parent container. I need to take a width of the image. Any help with this would be appreciated greatly.
I'm appending the dynamically created image element to document.
var img = new Image();
img.src = 'test.jpg',
img.onload = function() {
var addedImg = container.appendChild(img);
console.log(img.width); //old width.
}
The problem here is the fact if I take image dimensions right after container.appendChild(img)
it returns the source file dimensions because the appendChild has not finished yet(not repainted?) and dimensions are not re-calculated.
var addedImg = container.appendChild(img);
console.log(img.width) //returns original width of the image
So, I'm wondering if it is possible to catch the load event for appendChild?
I know it is possible using setTimeout/setInterval
, but I guess there should be more elegant solution.
var addedImg = container.appendChild(img);
setTimeout(function() {
console.log(img.width); //return correct resolution after image dimensions were recalculated
}, 1000);
The problem with setTimeout/setInterval is the fact I don't know when element is finally appended and repainted. I have to run it on a loop.
I was trying to listen to DOMNodeInsertedIntoDocument
and DOMNodeInserted
events however it does not work.
img.addEventListener("DOMNodeInserted", onImageInserted, false);
img.addEventListener("DOMNodeInsertedIntoDocument", onImageInserted, false);
function onImageInserted(event) {
console.log(img.width); //still wrong width
}
However, it seems to run right after appendChild is fired.
Here is the fiddle so you can see what I'm talking about: http://jsfiddle/0zyybmf2/
Note: please don't advise to check the width of the parent container. I need to take a width of the image. Any help with this would be appreciated greatly.
Share Improve this question edited Feb 23, 2015 at 9:02 Sray asked Feb 23, 2015 at 8:28 SraySray 6854 gold badges13 silver badges25 bronze badges 6-
2
Images have a
load
event. – elclanrs Commented Feb 23, 2015 at 8:30 -
ex:
img.onload=function(){alert(this.naturalWidth)}
– dandavis Commented Feb 23, 2015 at 8:38 - That's not what I'm talking about. This code is already inside img.load. This is about catching the repaint event. – Sray Commented Feb 23, 2015 at 8:38
-
1
appendChild has not finished yet
, what ? – Hacketo Commented Feb 23, 2015 at 8:42 - Sorry guys that I was not clear enough. I updated the post with a fiddle so you can see it in action. – Sray Commented Feb 23, 2015 at 8:52
3 Answers
Reset to default 2Unfortunately, it seems that you have to hand the controls back to the browser (using setTimeout()
as you did) before the final dimensions can be observed; luckily, the timeout can be very short.
container.appendChild(img);
setTimeout(function() {
console.log(img.width);
}, 0);
In other words, the repaint (and layout update) is done as soon as your function returns and before the setTimeout
fires.
Btw, it's advisable to only set the .src
property after you've attached the load handler; I've had to debug my code a few times before I realised that cached images may trigger the load handler immediately upon changing .src
.
Demo
var img = new Image();
var container = document.getElementsByTagName("div")[0];
container.appendChild(img);
img.onload = function() {
alert('Width = ' + img.width);
}
img.src = "https://picsum.photos/id/1015/600/400";
div {
width: 200px;
}
img {
display: block;
width: 100%;
height: 100%;
}
<div></div>
As 2022 MutationObserver can be a solution.
const callback = ( mutations, mutationObserver ) => {
mutationObserver.disconnect();
const MutationRecord = [...mutations];
console.log( MutationRecord );
};
let mutationObserver = new MutationObserver( callback );
mutationObserver.observe( document.querySelector( "#mmp-map-2b40f571" ), { childList: true, subtree: false } );
document.querySelector( "#mmp-map-2b40f571" ).appendChild( document.createElement( "div" ) );
<div id="mmp-map-2b40f571"></div>
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744836723a4596305.html
评论列表(0条)