Image width traces zero with onload when cached - javascript

I'm building a Javascript lightbox and I'm trying to adjust the size once the image has loaded. I'm using the code below, which works fine - it outputs the correct width once loaded.
My problem:
When I refresh, it will load the image instantly from the cache, and it seems to bypass the load. I get an instant zero for the width. Why does this happen?
My code:
var oImage = new Image();
oImage.src = 'http://mydomain.com/image.png';
container.html(oImage);
oImage.onload = function(){
alert(this.width);
}
** Update **
#Alex: This is the code I've tried with your plugin, I assume I'm probably doing something wrong. I'd be eager to get this working because your plugin looks quite good.
container.waitForImages(function() {
var cWidth = $(this).width();
alert("width: "+cWidth); // returns 0 - works first time but not cached
});
// Adding the image to the container for preload
container.html('<img src="mygraphic.png" />');

You need to do a few things...
Check the complete property of the img element.
Attach the load event before setting the src property.
Also, I found creating a new Image and assigning the src there is the best way to determine if the image has loaded or not.

You may want to switch the .html() and the .onload() calls.
If the image is loading from cache, I'm imagining that the .html() call completes before the script has had a chance to attach a function handler to the image's onload event. Therefore, effectively bypassing the load event itself (as the image has already loaded).
If it's still downloading the image (i.e. not cached), there will be more than enough time to call the .onload attach before the image completely finishes rendering.
While you're at it, you may want to do this the jQuery way, just so you're attaching events more similarly to DOM2 than DOM0.
var image = $('<img/>', {
src : 'http://mydomain.com/image.png'
}).load(function () {
alert(this.width);
})
// maybe clear container before if you want
.appendTo(container);
If we're going to have to set the src after the onload, we might as well do this instead:
var image = $('<img/>')
.load(function () {
alert(this.width);
})
.attr('src','http://mydomain.com/image.png')
.appendTo(container)
;
Hopefully that works cleanly.

This answer JavaScript: Know when an image is fully loaded suggests that you should set onload before setting src

Related

Detect inline image loading

I know there are many ways to detect if images have been loaded the traditional way (i.e. <img src="bar.jpg"/>, but is there a way to detect when images are completely loaded inline (as in, <div class="foo" style="background-image: url(bar.jpg)">)?
I am uploading images via FilePicker and the image is then set as the background image to the parent div.
The window load event signifies that all images in the page have been loaded.
From MDN:
The load event fires at the end of the document loading process. At
this point, all of the objects in the document are in the DOM, and all
the images and sub-frames have finished loading.
This occurs during the initial load of the page for the resources specified in the HTML of the page.
If you are dynamically setting an image to be a background image, there is no event for when that background image has been loaded. If you wanted to know when that image was loaded, you could load it yourself in an image object and watch the onload handler for that image object and then when loaded, you could set it as the background image. It would be cached at that point so the background would show immediately.
function setBackgroundNotify(imgURL, targetObj, callback) {
var img = new Image();
img.onload = function() {
targetObj.style.backgroundImage = "url(" + imgURL + ")";
callback();
};
img.src = imgURL;
}
#jfriend00 is correct. That answer has the advantage of having no dependence on other libraries.
However, if you are already using jQuery (as the tag on your question suggests), you can achieve the same thing with .on("load",...).
http://api.jquery.com/load-event/
Note, the .load(...) shortcut has been deprecated, so use .on("load", ...) instead. This has at least one advantage over window.onload. It allows queueing of multiple event handlers, whereas an inadvertent reassignment of window.onload will blow your handler away. Furthermore, in the off chance there are any browser incompatibilities with window.onload, the jQuery solution will likely automagically handle them.
You can (more or less) prove to yourself it is working with a little profiling:
$(document).ready(function() {
console.log("Document ready at " + Date.now());
});
$(window).on("load", function() {
console.log("First window on load at " + Date.now());
});
$(window).on("load", function() {
console.log("Second window on load at " + Date.now());
});
Assuming you've got some div's doing some really expensive background image loading, you should see a noticeable lag in time between document ready and the first window on load.

Gif loader while loading heavy png image

I load png image generated by server-side PHP script (chart) to the HTML IMG-element <img id="chart"> using following JS code:
$('#chart').attr('src', 'chart.php');
The PNG-image generation and downloading takes about 1 second, so I want to show gif loader while image is loading. How to implement this feature with JS?
For balance this is very simple to do in plain JS:
var preload = function(element, src) {
var img = new Image();
// Apply onload before applying src attribute to avoid IE prematurely firing
img.onload = function() {
// Replace #chart with image
element.parentNode.replaceChild(img, element);
};
img.src = src;
}
preload(document.getElementById('chart'), 'chart.php?_...');
$('#chart').attr('src', 'chart.php').load(function(){
//something
});
In case the browser caches it, you may way to add something to the query string to break that. Either way, you need to listen for the image's load event, which should be bound before setting its src (in case it's cached):
var target_url = 'chart.php?_=' + (new Date()).getTime();
// Show "loading"
$('#chart').on("load", function () {
// Hide "loading"
}).attr('src', target_url);
Reference:
http://api.jquery.com/load-event/
Note the caveats near the bottom of that reference, referring to the event when working with images:
It doesn't work consistently nor reliably cross-browser
It doesn't fire correctly in WebKit if the image src is set to the same src as before
It doesn't correctly bubble up the DOM tree
Can cease to fire for images that already live in the browser's cache

Javascript slowly "flush" DOM Tree

I have really strange problem. I'm trying to get width and height of an image using following way:
Create a image tag and add .src to it.
add this image tag to document.body.
making this image tag visible (display:inline).
getting .offsetWidth and .offsetHeight of element.
hidding image tag(display:none);
all this is done using JS and it all work really well on my localhost, but when I uploaded a site to my client hosting provider I was amazed. offsetWidth and .offsetHeight was 0 in step 4. Why do that happen? I think that I need some kind of "flush" after step 3 before step 4, but I'm not exactly sure. Any suggestions ? Thank you.
You have to wait for the image to actually load over the network. You don't need to add the thing to the DOM either:
var img = new Image();
img.onload = function() {
handleImageSize(this.width, this.height);
};
img.src = "http://whatever.com/your/img.jpg";
Here, "handleImageSize" would be a function you write to do whatever it is you need to do with the image dimensions.
This was probably caused by the image not being loaded yet. Try something like this:
img.onload = function() {
// get the offsetWidth and offsetHeight
}
As other answers suggest, is due to the image not being fully loaded by the DOM. This was working fine on your local server as I suspect you were loading images locally, meaning they were almost instantaneous; however after moving them to the server there is a slight delay. It's an easily overlooked problem, that is easily fixed.
Other answers will do the trick; but here's the jQuery version for sake of argument
var img = $('<img>', {
src: 'http://dummyimage.com/150/000/fff.gif'
}).one('load', function() {
var offsets = $(this).offset();
});
$('body').append(img);
jsFiddle

HTML / Javascript wait for graphics to be drawn

I've heard about the onload function which is called after the element is fully loaded.
In the case of graphics or images, does that mean it will wait until the image is displayed in the browser?
<body onload="foo()">...
<img onload="bar();"....
If not, is there a way to get the event when all graphics are drawn and images are displayed on a page?
In my case it´s only one 1600*1200 jpeg image and i draw on it. But the image has to be displayed before i start drawing, even with the onload event i see the drawed lines before the image appear.
Yes body onload will wait until all images (and other content) are loaded/displayed in the browser. The img onload will wait until that specific image has loaded/is displayed
Images have a complete property that's true when they are loaded.
e.g. would test if everything has loaded:
var allImagesLoaded = true;
$("IMG").each(function(){ allImagesLoaded &= $(this).attr("complete"); });
if(allImagesLoaded){ alert("Done!");}
Images raise a load event once they've finished loading
why dont you keep a counter for your images that will decrement by one on each image load.
check if it equal to 0 then call some another function.
in this way you can do the thing you want to when all images are loaded
$(function() {
$('img').one('load',function() {
// fire when image loads decrement the counter
if counter ==0
fireanotherfunction()
});
});
by above code u can attain your purpose
When reading the jQuery ready API documentation here:
While JavaScript provides the load event for executing code when a
page is rendered, this event does not get triggered until all assets
such as images have been completely received.
So onload is launched after everything has been loaded (and displayed).
See the window.load event:
The load event fires at the end of the document loading process. At this point, all of the objects in the document are in the DOM, and all the images and sub-frames have finished loading.
This is exact what you want, I believe.
JQuery's $(document).ready is not what you want:
In cases where code relies on loaded assets (for example, if the dimensions of an image are required), the code should be placed in a handler for the load event [instead of the ready event].
If you're using plain JS, window.load is what you want.
If you are using jQuery, you'll want $(document).load.
try jquery ready function
$(document).ready(function(){
bar();
});
I'm not sure if it works, but it's a try :D
I have the same problem developing a web view for an Android app. The load events (both for window and image element) as well as the complete state of the image element fire too early. My (svg) image has not yet finished drawing and thus calculations on the size go wrong.
The only workaround that I have found is a very short timer (1ms or maybe 10ms). That works for me because I have only one such image to consider. And since I start this timer when the image data has already loaded, this short lapse should be long enough for the device to paint the image.
window.addEventListener('load', function() {
var img = document.getElementById('logo');
window.setTimeout(function(){
var imgRatio = img.naturalWidth / img.naturalHeight;
var renderedWidth = parseInt(window.getComputedStyle(img).width.match(/(\d+)px/));
console.log(renderedWidth, img.complete);
if (renderedWidth < img.naturalWidth) {
img.style.height = (renderedWidth / imgRatio) + 'px';
}
}, 1);
}
Instead of the window load event, the image's load event should also work. But I found it safer to wait for everything, because other elements might affect the drawing of my image.

How to get the true image height using JQuery?

I want to load html , and then get the true image height.
$("#cover").html(stuff); //this has the image inside it
$(function(){
console.log($("#cover img").height()); //sometimes it's 0
});
For some reason, height is sometimes 0. Could it be because the image hasn't been fully loaded yet, and JQuery sees it as 0? If so, how do I overcome this? Is there a callback or something when the image is loaded?
You can use the .load() method of jQuery
$('#cover').html(stuff);
$('#cover img').load(function () {
console.log($(this).height());
};
Why do the console.log inside an anonymous function? Have you tried this?
$("#cover").html(stuff); //this has the image inside it
console.log($("#cover img").height());
//locate the image(s)
$("#cover img").each(function(){
//Build a new Image Object outside the DOM
//that way, CSS won't affect it
var img = new Image();
//add a callback when loaded
img.onload = function(){
//your width and height
//img.width
//img.height
}
//use the image src to load
//use attr() to resolve path issues across browsers
img.src = $(this).attr('src');
});
try to using load method method that we can take advantage of to make this work the way we want it too.
The problem we have right now is that, in the Webkit browsers, the jQuery code runs when the DOM is ready and the DOM is ready before the image has been loaded. So the code runs but since there’s no image to get a width of, we get 0 for the image’s width. We can use the load method to make the code wait until the window has loaded entirely before it runs.
$(window).load(function() {
console.log($("#cover img").height());
});
try using attr() to get the height:-
$("#yourElemengtID").attr('height')
Here is a piece of small code i used before hope this will help you
On my displayed image when mouse is in call this function
function MouseIn()
{
var src;
//to get original image size
var img =$(this);// displayed image
var theImage = new Image();// create a cache image
var imgsource =img.attr("src");// take the src of displayed image
theImage.src = imgsource;// give cached image the source of displayed image
var original_height = theImage.height// take height of image from the source
var original_width = theImage.width;//take width of image from the source
// to get the displayed image size
var Image_displaysize_width= img.width();
var Image_displaysize_height= img.height();
}
Don't you mean to do something like this?
jQuery("#myImg")[0].naturalHeight
better still don't use overhead of jQuery when possible.
document.getElementById('myImg').naturalHeight

Categories

Resources