简体   繁体   English

Javascript appendChild onload 事件

[英]Javascript appendChild onload event

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.这里的问题是,如果我在container.appendChild(img)之后立即获取图像尺寸,它会返回源文件尺寸,因为 appendChild 尚未完成(未重新绘制?)并且未重新计算尺寸。

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?所以,我想知道是否可以捕获 appendChild 的加载事件?

I know it is possible using setTimeout/setInterval , but I guess there should be more elegant solution.我知道使用setTimeout/setInterval是可能的,但我想应该有更优雅的解决方案。

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. setTimeout/setInterval 的问题是我不知道元素何时最终被附加和重新绘制。 I have to run it on a loop.我必须循环运行它。

I was trying to listen to DOMNodeInsertedIntoDocument and DOMNodeInserted events however it does not work.我试图收听DOMNodeInsertedIntoDocumentDOMNodeInserted事件,但它不起作用。

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.但是,它似乎在 appendChild 被触发后立即运行。

Here is the fiddle so you can see what I'm talking about: http://jsfiddle.net/0zyybmf2/这是小提琴,所以你可以看到我在说什么:http: //jsfiddle.net/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.对此的任何帮助将不胜感激。

Unfortunately, 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;不幸的是,您似乎必须将控件交还给浏览器(像您一样使用setTimeout() )才能观察到最终尺寸; 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.换句话说,只要你的函数返回并且在setTimeout触发之前,重绘(和布局更新)就会完成。

Btw, it's advisable to only set the .src property after you've attached the load handler;顺便说一句,建议仅在附加负载处理程序设置.src属性; 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 .在我意识到缓存的图像可能会在更改.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.因为 2022 MutationObserver可以成为一个解决方案。

 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM