2015-02-23 4 views
2

Я добавляю динамически созданный элемент изображения в документ.Javascript appendChild onload event

var img = new Image(); 
img.src = 'test.jpg', 
img.onload = function() { 

    var addedImg = container.appendChild(img); 
    console.log(img.width); //old width. 
} 

Проблема здесь заключается в том, если я размеры изображения сразу после container.appendChild(img) он возвращает размеры исходного файла, поскольку AppendChild еще не закончена (не перекрасили?) И размеры не пересчитывается.

var addedImg = container.appendChild(img); 
console.log(img.width) //returns original width of the image 

Итак, мне интересно, если это возможно, чтобы поймать событие нагрузки для AppendChild?

Я знаю, что можно использовать setTimeout/setInterval, но я думаю, должно быть более элегантное решение.

var addedImg = container.appendChild(img); 
setTimeout(function() { 
    console.log(img.width); //return correct resolution after image dimensions were recalculated 
}, 1000); 

Проблема с SetTimeout/setInterval является тот факт, я не знаю, когда элемент окончательно добавляется и перекрасили. Я должен запустить его в цикле.

Я пытался прослушать DOMNodeInsertedIntoDocument и DOMNodeInserted событий, однако это не сработало.

img.addEventListener("DOMNodeInserted", onImageInserted, false); 
img.addEventListener("DOMNodeInsertedIntoDocument", onImageInserted, false); 

function onImageInserted(event) { 
    console.log(img.width); //still wrong width 
} 

Однако, похоже, что сразу после запуска appendChild.

Вот скрипка, так что вы можете увидеть, что я говорю о: http://jsfiddle.net/0zyybmf2/

Примечания: пожалуйста, не советуете проверить ширину родительского контейнера. Мне нужно взять ширину изображения. Любая помощь с этим была бы оценена очень.

+2

Изображения имеют 'load' событие. – elclanrs

+0

ex: 'img.onload = function() {alert (this.naturalWidth)}' – dandavis

+0

Это не то, о чем я говорю. Этот код уже находится внутри img.load. Речь идет об улавливании события перерисовки. – Sray

ответ

1

К сожалению, вам кажется, что вы должны вернуть управление в браузер (используя setTimeout(), как вы это делали), до того, как можно будет увидеть окончательные размеры; к счастью, таймаут может быть очень коротким.

container.appendChild(img); 
setTimeout(function() { 
    console.log(img.width); 
}, 0); 

Другими словами, перекрасить (и обновление макета) выполняется как только ваша функция возвращает и перед setTimeout пожаров.

Btw, желательно установить .src недвижимость после вы прикрепляете погрузчик; Мне пришлось несколько раз отлаживать код, прежде чем я понял, что кешированные изображения могут сразу вызвать обработчик нагрузки при изменении .src.

Demo

+1

Спасибо. Но я знаю «setTimeout». Я упомянул об этом в оригинальном вопросе.Проблема с 'setTimeout' заключается в том, что я не знаю, когда перерисовывает ее. Единственное возможное решение - проверить, была ли изменена ширина или нет внутри setTimeout (я думаю, что 'setInterval' было бы еще лучше для этого). Мне интересно, есть ли другое решение. – Sray

+0

@Sray Ну, вы установите значение тайм-аута на 1 секунду, что не нужно; также, почему вам нужно точно знать, когда перерисовывается? это делается, как только ваша функция заканчивается, вот и все. –

+0

О, я вижу сейчас. Благодарим вас за прекрасное объяснение. – Sray

1

var img = new Image(); 
 
var container = document.getElementsByTagName("div")[0]; 
 
container.appendChild(img); 
 

 
img.onload = function() { 
 
    alert('Width = ' + img.width); 
 
} 
 

 
img.src = "http://globe-views.com/dcim/dreams/image/image-03.jpg";
div { 
 
    width: 200px; 
 
} 
 

 
img { 
 
    display: block; 
 
    width: 100%; 
 
    height: 100%; 
 
}
<div></div>

Смежные вопросы