Insérer un délai d'objet (jquery)?

J'autorise l'utilisateur à insérer un objet, une image, puis j'appelle une fonction sur cet objet. Qu'est-ce qui me semble aléatoirement, parfois ça fonctionne et parfois pas, je suppose que cela ne concerne pas le DOM qui n'est pas encore mis à jour?

//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); } 

Parce que si je déclenche manuellement cette dernière fonction avec un bouton après une seconde, cela fonctionne toujours.

 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%' ); } 

J'essaye de zéro avec le même résultat. Parfois, l'image a été chargée et, parfois, elle ne fonctionne pas de façon aléatoire, avec des images plus grandes (prenant plus de temps à charger dans le navigateur), évidemment, échoue plus fréquemment. À l'heure actuelle, je l'ai contourné avec un temps de temporisation, mais ce n'est pas une solution assez: – / peut-être que je pourrais mettre une boucle sur la recherche ('img') qui continue de vérifier l'image et ne procède-t-elle qu'une fois? Mais cela pourrait me coller dans un problème de boucle infinie à certains moments?

Cela pourrait-il fonctionner pour vous?

  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); } 

Et BTW, vous avez des ID de duplication pour myNewImg et imgInner

Au lieu d'interroger le DOM immédiatement après l'ajout, enregistrez simplement une référence à l'élément, puis faites référence à cela. Comme:

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

En outre, je pourrais avoir juré que vous ne pouvez pas définir la clé d'un objet en tant que class puisqu'il s'agit d'un identifiant réservé, sans guillemets … alors utilisez "class": "object_image" . En outre, vous avez eu une virgule supplémentaire après la valeur de class … c'est une erreur de syntaxe, au moins dans IE.

Vous pouvez utiliser la fonction de chargement de jquery. Voici un exemple avec votre 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")); }); } 

Avez-vous essayé d'utiliser la référence que vous avez déjà?

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

Peut-être que ça fonctionne

EDIT : Vous pouvez mettre un délai 0 pour ajouter votre fonction après le rendu du navigateur …

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

Vous ne pouvez pas accéder aux images en largeur et en hauteur jusqu'à ce que les images soient chargées. C'est pourquoi le setTimeout fonctionne parfois pour vous. Utilisez la fonction image.load () call back pour déclencher le code que vous devez exécuter après l'importation de l'image.

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

Vous pouvez le faire sans jquery, utilisez simplement l'observateur de mutation es5 et un événement de chargement

 (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)); 

Un exemple en direct est sur jsfiddle

Vous pouvez en savoir plus sur MutationObserver chez mdn