How does the browser know if an image is loaded? - javascript

I need to have a function called after a larger image is loaded on the page. I've tried some various solutions that I've found on here and around the web, but none either fit or work. Here's what I've tried that seems to make the most sense...and this is using jQuery
var imgs = $('#bgStage img.bg'),
imgCnt = imgs.length,
cnt = 0;
imgs.load(function () {
cnt++;
if (imgCnt === cnt) {
homeSlider();
}
}).each(function () {
if (this.complete) {
$(this).trigger('load');
}
});
This doesn't seem to wait until the img.bg is loaded. The homeSlider() function is called and started as I still see the image still loading.
So, I am wondering how a browser determines an image is loaded? Is it when it can read the width and height? Because I am defining the width and height in the CSS for the image to force it to be a certain size.
If anyone has any insight as to what makes the onload event fire for an image, that'd be great! Thanks.

You can always check for $('img').length();

Here's a sample code that should work. I did a project that needed this and I remember that some problems might include:
The browser caches the image (IE i believe) so I had to append ?[random] at the end
Maybe you have to set the src javascriptly so that your event is hooked at the right time
Sample code:
<!DOCTYPE html>
<html>
<head>
<title>Sample</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
$('#imageSample')
.load(function(){
alert($('#imageSample').width());
alert($('#imageSample').height());
})
.attr('src', 'http://www.gimp.org/tutorials/Lite_Quickies/quintet_hst_big.jpg?' + new Date());
});
</script>
<style type="text/css"></style>
</head>
<body>
<img id="imageSample" src="" alt="" />
</body>
</html>

Images might be cached, try this: http://github.com/peol/jquery.imgloaded/raw/master/ahpi.imgload.js

Use something simple like so:
var loaded = false;
var len = $('#bgStage img.bg'), c = 0;
$('#bgStage img.bg').each(function(){
$(this).attr('src',$(this).attr('src') + new Date()); //Remove caching.
$(this).bind('onload',function(){
//Other Stuff here!
if(c == len)
{
HomeSlider();
}
c++; //Increment
});
});
Tell me how it goes :)

Each image has a complete property. Unfortunately not all browsers support it. They always report true, even if the image hasn't loaded at all. IE gets it right. ;-)
http://simon.html5.org/test/html/semantics/img/src/ (not mine)

Related

jQuery playlist function error: function undefined

I'm trying to create a .mp3 player to just loop through audio tracks, but I keep getting error on Firebug that the main function I use is undefined, although I do define it. Here is the code:
$(document).ready(function() {
var counter=1;
var nextSong = function(){
if (counter <= 3) {
$('audio').src="audio/audio"+counter+".ogg";
$this.load();
$this.play();
counter++;
}
else {
counter=0;
$('audio').src="audio/audio"+counter+".ogg";
$this.load();
$this.play();
};
};
});
And my markup is simply:
<!DOCTYPE html>
<head>
<title>Dokimastiko Audio Player</title>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/dokimastiko.js"></script>
</head>
<body>
<audio src="audio/audio1.ogg" controls autoplay onended="nextSong();"></audio>
</body>
Any thoughts?
I debated on whether to give you a full lesson on why your code is pretty bad... And since I have little on my plate at work right now I'll do so... :P
First of all the $this you have there is undefined, so obviously calling a method on it is going to be undefined as well.
You probably copied the code from somewhere, which is fine, but you need to be able to copy is smartly instead of blindly.
.... you changed your code midway of my post, so update:
$(this) is the same as $(document) since that is the context of this within $(document).ready(function() {})
So, nope, still wrong.
So the first modification, it should be:
$('audio').load();
$('audio').play();
But actually that is still wrong. Because $('audio') is a jquery object, and it does not contain the DOM-level methods load and play directly, so you need to get the DOM object:
$('audio').get(0).load();
$('audio').get(0).play();
Now you would be wondering why the .get(0), it's because $('audio') is a collection of all the matches to 'audio', so get(0) would return the first one only.
This is prone to breakage if you decide to add more audio tags to the page, so you should give the audio tag a unique identifier:
<audio src="audio/audio1.ogg" controls autoplay onended="nextSong();" id="audio1"></audio>
And then use the id in your jquery selector:
$('#audio1').get(0).load();
$('#audio1').get(0).play();
This is still abit verbose, but given that you only need to do this, this is the simplest way.
UPDATE:
As per suggested by #JanDvorak here is a example that uses jquery events as well
Fiddle: http://jsfiddle.net/MpBP5/1/
jQuery(document).ready( function($) {
$('#audio1').bind('ended', function(e) {
alert('end');
});
});
I can also keep going on this "lesson", you should try not to define your music urls that abstractly, what if someone just leaves your page on and it hits a file which, for that counter #, doesn't exist?
I would declare an array of files you wish to load:
var library = [
'http://www.archive.org/download/bolero_69/Bolero.mp3',
'http://www.archive.org/download/MoonlightSonata_755/Beethoven-MoonlightSonata.mp3',
'http://www.archive.org/download/CanonInD_261/CanoninD.mp3',
'http://www.archive.org/download/PatrikbkarlChamberSymph/PatrikbkarlChamberSymph_vbr_mp3.zip'
];
var currentIndex = 0;
Then loop through the list:
jQuery(document).ready( function($) {
$('#audio1').bind('ended', function(e) {
currentIndex++;
if (currentIndex > library.length-1) {
currentIndex = 0;
}
this.src = library[currentIndex];
$('#url').html(library[currentIndex]);
});
$('#audio1').attr('src', library[currentIndex]);
$('#url').html(library[currentIndex]);
});
http://jsfiddle.net/MpBP5/3/
If you don't want a fixed list of audio files to play (which you really should), you can generate the array with at least some rules.

Only load the background-image when it has been fully loaded?

Well, the title pretty much describes my question:
How to load the background-image dynamically after it has been fully loaded? Sometimes, I must use backgrounds that are so big that it can take a while for the browser to download it. I'd rather 'load it in the background' and let it fade in when it has been fully loaded.
I think jQuery would be best to be using, but I also want my background to appear if JavaScript has been disabled. If this really isn't possible, so be it, but I think it is?
Best regards,
Aart
........
EDIT:
Thanks a bunch, guys! I've been bugged with this for ages and just couldn't think of a nice and easy way.
I converted Jeffrey's Javascript-solution into a jQuery one, just because jQuery's built-in fade looks so awesome.
I'll just post it here in case anyone else has the same issue:
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'></script>
<script type='text/javascript'>
$(document).ready(function() {
$('#img').css('opacity','0').load(function() {
$(this).animate({
opacity: 1
}, 500);
});
});
</script>
<img src='yourimage.jpg' id='img'/>
If the image is included with an img element:
<img src="bg.jpg" id="img" onload="this.style.opacity='1'">
<script>
document.getElementById("img").style.opacity="0";
</script>
That should load the image normally if JavaScript is disabled, but show it only once it loads assuming it's enabled.
One thing to note (that I overlooked): some browsers will not even attempt to load an image if its display property is none. That's why this method uses the opacity attribute.
You can't do it when JS is disabled. However, what you can do is set the background image in CSS and then use the following script (assuming the element has the ID myelem).
(function() {
var elm = document.getElementById('myelem'),
url = 'background image URL here';
elm.style.backgroundImage = "none";
var tmp = new Image();
tmp.onload = function() {
elm.style.backgroundImage = "url('"+url+"')";
// or insert some other special effect code here.
};
tmp.src = url;
})();
EDIT: Although, make sure your background images are optimal. If they are PNG, try having them Indexed with as small a colour table as possible, or make sure the alpha channel is removed if there is no transparency. If they are JPEG, try adjusting the compression.
Check the example on this page:
http://www.w3schools.com/jsref/event_img_onload.asp
Using "image.onload" will start your code only when the image is ready
Without javascript you can't have events, so you won't be able to know if the image is loaded, at least for the first rendering.
You can also use a css preload (put the image as a background in a hidden div), but that would work better in your first refresh and not while loading.
You can set a variable to the image, and when it loads, set it to the body background:
var my_bg = new Image();
my_bg.src = "url(mybackground.png)";
document.style.backgroundImage = my_bg;
What you are looking for is an image onLoad method. If you set the image with a display:none it wont be visible. To get around the possible lack of javascript, you do the following:
<body style="background-image:url(image.png);">
<img src="image.png" style="display:none" onLoad="changeBackground();" />
</body>
<script>
document.body.style.backgroundImage = "";
function changeBackground(){
document.body.style.backgroundImage = "url(image.png)";
}
</script>
This way, if javascript isnt enabled, the bg will load as normal. If it is, it will display at the end

Check if image exist

I use the following code to refresh an image in the browser. I just want to modify the code in order to first check if the image exists and then display the image. If the image does not exist I will only refresh the image to the previous version of the picture. Can someone point me how to accomplish this using javascript or jquery?
<html>
<head>
<script language="JavaScript">
function refreshIt(element) {
setTimeout(function() {
element.src = element.src.split('?')[0] + '?' + new Date().getTime();
refreshIt(element);
}, 500); // refresh every 500ms
}
</script>
</head>
<body>
<img src="swt.png" name="myCam" onload="refreshIt(this)">
</body>
</html>
Edited: I need a combination of the already implemented functionality plus the file checking.
Functionality:
if image exist
refresh image
else
show cached image
Something like this:
$('#image_id').error(function() {
alert('Image does not exist !!');
});

javascript : simple delayed image show

I'm trying to write a simple javascript snippet which delays the image loading by a certain number of millisecs below.
<html>
<head>
<script type="text/javascript">
function SetTimer()
{
var Timer = setInterval("showImage()",3000);
}
function showImage()
{
document.getElementById('showImage').style.visibility = 'visible';
}
</script>
</head>
<body onLoad="SetTimer()" style="visibility:hidden">
<div id=showImage>
<img src="gwyneth_paltrow_2.jpg">
</div>
</body>
</html>
Am I approaching this incorrectly?
thanks in advance
This is basically an OK approach.
There are some bugs, namely:
document.getElementByID('showImage')style.visibility = 'hidden';
getElementByID should be getElementById
needs a dot after ('showImage')
You are setting the visibility to 'hidden' in order to show it. Instead, you should start out as hidden, and then make it appear instead of disappear.
document.getElementById('showImage').style.visibility = 'hidden';
Well, the code is backwards given the stated goal of delaying the appearance of the image. If I just use your code as a basis, then I would have the visibility of the image as hidden, using CSS, and then trigger the display to visible on the timer.
However, having said that... This doesn't delay the loading of the image, it merely delays the display of it. The other way to handle it is to use the timer to load an Image object in Javascript and then insert it into the DOM. This, then, will actually delay the loading of the image for 3 seconds. Something like this:
function showImage()
{
var myImage = new Image();
myImage.src = "gwyneth_paltrow_2.jpg";
document.getElementById("showImage").appendChild(myImage);
}
I'm doing that from memory, so syntax may not be entirely correct.

Javascript onload event to resize image help

This might be a simple one for you guys, im learning Javascript and have hit a problem. I am trying to have the script resize a particular image on the page when onload is called like so:
<script type="text/javascript">
function resizeSampleImage()
{
document.getElementById("sampleImage").style.height = (document.body.clientWidth) * 0.2;
}
</script>
...
<body onload = "resizeSampleImage();" >
...
<img id="sampleImage" src="Images/BP snip.jpg" alt="BuildingPeople.uk.com" />
apologies, forgot to mention that is doesn't work! after loading the page in multiple browsers the image stays it native size and the error consoles say they fail to parsing value for height. Declaration dropped.
I have tried lots of different ways but cannot seem to get it to work.
(document.body.clientWidth) * 0.2 will give you an integer. The CSS height property accepts a length.
Add some units.
There is a live example at http://jsbin.com/uyihe4
You can see the zoom effect when loading. I have only changed the
document.getElementById("sampleImage").style.height
to
document.getElementById("sampleImage").height
Well, your problem is that the images may not be ready when you apply the styles to them.
Use this function instead (note it takes a DOM object):
var imgLoader = function(domImg) {
var imgObj = new Image();
imgObj.onload = function()
{
// apply styles
domImg.style.height = "100px";
}
imgObj.src = domImg.src;
}
Though I haven't figure out the problem. But the following code snippet works for me (Tested in Chrome 8.0 and IE9.0Beta).
<html>
<head>
<title>test</title>
<script type="text/javascript">
function resizeSampleImage()
{
document.getElementById("sampleImage").style.height = (document.body.clientWidth) * 0.5;
}
</script>
</head>
<body onload="resizeSampleImage();">
<img id="sampleImage" src="http://news.mydrivers.com/Img/20101217/S03405153.jpg">
</body>
</html>

Categories