Insert object delay (jquery)?

I allow the user to insert an object, an image, and then I call a function on that object. What seems random to me, sometimes it works, and sometimes not, I believe that this is due to the fact that the DOM is not updated?

//add a new image function add_image(img) { var objCount = count_objects() + 1; var objId = 'object_'+objCount; var myNewImg = jQuery('<div/>', { id: objId, class: 'object_image invisible', }).appendTo('#objectbox'); //sätt objektnamnet (användaren kan ändra senare) $('#'+objId).attr('namn', objId) //sätt låsta proportioner som standard $('#'+objId).addClass('lockedAspectRatio') //lägg till bilden i detta element var imgInner = jQuery('<img/>', { id: objId, class: 'object_image_inner', src: img, }).appendTo( '#'+objId ); window.objectCounter++; prepare_editmode(); //reset the flag and the temporary image field now that image adding is complete $('#imageGhost').val(null); //fixa rätt storlek på bilden setTimeout(function(){ restoreSize(myNewImg,imgInner); $(myNewImg).removeClass('invisible'); }, 1500); } 

Because if I manually start this last function with a button after a second or so, it always works.

 function restoreSize(myImg,imgInside) { if (imgInside == null) { console.log("nothing passed"); var imgInside = $(myImg).find('img'); } else { console.log("passed alright"); } //remove fixed dimensions on containing div $(myImg).css("height", 'auto' ); $(myImg).css("width", 'auto' ); //remove the 100% attribute on the image $(imgInside).css("width", 'auto' ); $(imgInside).css("height", 'auto' ); //get calculated dimensions of div once img original size determines it var newWidth = $(myImg).css("width"); var newHeight = $(myImg).css("height"); //...and set them firmly. $(myImg).css("width", newWidth ); $(myImg).css("height", newHeight ); //restore the height/width 100% property to image in case of new resize $(imgInside).css("width", '100%' ); $(imgInside).css("height", '100%' ); } 

I try to set the timeout to zero with the same result - sometimes the image is loaded, and sometimes not so that it works randomly, with large images (with a long download time in the browser), of course, it fails more often. Right now I went around it with a timeout in seconds, but this is not a very pretty solution: - / maybe I could put a loop in find ('img') that continues to scan the image only after it is detected? But can this run into the problem of an infinite loop several times?

+6
source share
6 answers

Could this work for you?

  function add_image(img) { var objCount = count_objects() + 1; var objId = 'object_' + objCount; var myNewImg = jQuery('<div/>', { id: objId, class: 'object_image invisible' }).appendTo('#objectbox'); $('#' + objId).attr('namn', objId) $('#' + objId).addClass('lockedAspectRatio') var imgInner = jQuery('<img/>', { id: objId, 'class': 'object_image_inner', src: img }).load(function () { imgInner.appendTo('#' + objId) restoreSize(myNewImg, imgInner); $(myNewImg).removeClass('invisible'); }); window.objectCounter++; prepare_editmode(); //reset the flag and the temporary image field now that image adding is complete $('#imageGhost').val(null); } 

and BTW you duplicate identifiers for myNewImg and imgInner

+2
source

Instead of requesting the DOM immediately after adding, just save the link to the element and then specify it. How:

 var div = jQuery("<div/>", { id: objId, "class": "object_image" }).appendTo("#objectbox"); restoreSize(div); 

Also, I could swear that you cannot set the object key as a class , since it is a reserved identifier, without quotes ... so use "class": "object_image" . Also, after the class value, you had an extra comma ... that there was a syntax error, at least in IE.

+1
source

u can use load jquery function . Here is an example with your code:

http://jsfiddle.net/UhUb7/

  var images = [ "http://upload.wikimedia.org/wikipedia/commons/4/4b/Apple_pie.jpg" ] $(document).ready(function(){ addImage(images[0]); }); function addImage(url){ var holder = $('<div class="object_image invisible">'); var image = $('<img src="'+url+'" />'); holder.append(image); $("#objectbox").append(holder); image.load(function(){ holder.show('slow'); // alert(image.css("width")); }); } 
+1
source

Have you tried using the link that you already have?

 var obj = jQuery('<div/>', { id: objId, class: 'object_image', }).appendTo('#objectbox'); restoreSize(obj); 

Maybe it works

EDIT : You can put a timeout of 0 to add your function after rendering the browser ...

 var obj = jQuery('<div/>', { id: objId, class: 'object_image', }).appendTo('#objectbox'); setTimeout(function(){ restoreSize(obj) }, 0); 
0
source

You cannot access the width and height of images until the images load. This is why setTimeout works for you sometimes. Use the image.load () callback function to run the code that you want to run after loading the image.

  var imgInner = jQuery('<img/>', { src: img }).load(function () { jQuery(this).appendTo('#' + objId) restoreSize(myNewImg, this); //and so on }); 
0
source

You can do it without jquery, just use es5 mutation observer and load events

 (function (global) { "use strict"; if (!("MutationObserver" in global)) { global.MutationObserver = global.WebKitMutationObserver || global.MozMutationObserver; } function loadImage(e) { var img = e.target, width = img.clientWidth, height = img.clientHeight; img.removeEventListener('load', loadImage, false); alert("Image loaded: width: " + width + " height: " + height); } var observer = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { switch (mutation.type) { case 'childList': Array.prototype.forEach.call(mutation.target.children, function (child) { if (child.id === "smiley") { child.addEventListener('load', loadImage, false); } }); break; default: } }); }); var container = document.getElementById("container"); observer.observe(container, { childList: true, characterData: true, subtree: true }); container.innerHTML = "<img id='smiley' src='http://1.bp.blogspot.com/-b1Z0R5ExM9s/TdWbeGQ-wdI/AAAAAAAAAPI/Ft52XTSxs0s/s1600/blue+sky+wallpaper+%25289%2529.jpg'/>"; }(window)); 

Expected Example: jsfiddle

You can learn more about MutationObserver at mdn

0
source

All Articles