PDA

View Full Version : Anyway to know if an image did NOT display in the browser?



monaya
02-27-2009, 12:45 AM
Is there anyway by javascript to know if an image didn't load; I mean that an image didn't display.

monaya
02-27-2009, 03:22 AM
You didnt do that to to mess with me right??

I tried that and kept getting and alert that said nope that wouldn't go away unless I forced the system to quit the browser.. :(

Anyway, what I'm really trying to do is actually verify that an image does exist and does in fact load.

I see you now deleted your post.

magicyte
02-27-2009, 03:26 AM
Sorry about that. I didn't test the code before I posted it. After I posted it, I tested and it didn't work (go figure :rolleyes:). Something similar to the code I posted may work. I know that attaching the 'onload' event to an image can do something when it loads, but this has to be done via javascript. I tried, but I failed. If you still want the code, here is the browser-compatible "addEvent" function:


function addEvent(el, ev, response) {
var elem = document.getElementById(el);
if (elem.addEventListener)addEventListener(ev, response, false);
else if (elem.attachEvent) {
var res = function() {
response.apply(elem);
};
elem.attachEvent("on" + ev, res);
} else elem["on" + ev] = response;
}

WHERE I'M STUCK: To make sure that an element exists, you have to attach the event in a window.onload function. Problem: the image may already be loaded when window loads. Javascript wouldn't parse in time, thus the image that you want to check is loaded is already loaded or may already be loaded and you can't attach an onload event to something that has already loaded... If the image is a larger file, it could possibly work. Now, the way you would want to avoid this is make it attach the onload event to the element before it loads. You then wouldn't place one of those functions into the window.onload function. This would parse BEFORE the window loads. Problem: the element wouldn't even EXIST before the pages loads -.- I don't see any other way to do this.

monaya
02-27-2009, 03:33 AM
Oh its ok.

I'm not sure how to use the code you posted in relationship with the image. I'm not fully sure if you meant that the code works or does something else?

monaya
02-27-2009, 03:35 AM
I'm actually trying to know that an image does NOT exist. I hope that makes sense...

magicyte
02-27-2009, 03:40 AM
Is there anyway by javascript to know if an image didn't load; I mean that an image didn't display.

I'm actually trying to know that an image does NOT exist. I hope that makes sense...

HOLD IT! You want to check if an images EXISTS? NOT if an image HASN'T LOADED? Or vice versa? Or even BOTH? Or check to see if it loads to therefore see if it exists? :confused:

Nile
02-27-2009, 03:44 AM
How about this?:


<script type="text/javascript">
var newImage = new Image();
newImage.src = "image.png";
newImage.onerror = function(){
alert("Your picture doesn't exist. :(");
};
</script>

monaya
02-27-2009, 03:55 AM
Can I connect this code with an image i already have coming in. I think your code creates a new image.

magicyte
02-27-2009, 03:57 AM
Please post a link to the page on your site that contains the problematic script so we can check it out. This helps us help you.
Haha- I couldn't resist.

If you do not have a website, please post your code so we can check it out.

monaya
02-27-2009, 04:00 AM
There's no problematic script yet. I jsut have a a user generated image:
<img src="whatever.jpg" />

I just want to know if the image exists or not and put a message in place.

magicyte
02-27-2009, 04:03 AM
Oh. Then do what Nile was saying. Take the source of the image that the user submits or whatever an put it in that "new Image('image here');' declaration. Replace 'image here' with the image name. That's just about it.

monaya
02-27-2009, 04:08 AM
I see. Can you help me configure this. I have a user submitting a full url of an image in a simple form. I want to check that the form exists before allowing the submit? if it doesnt exists I dont want the form to submit.

Nile
02-27-2009, 01:05 PM
Nonono...


<img src="image.png" onerror="alert('Your picture doesn\'t exist!');" />

monaya
02-27-2009, 02:32 PM
Nonono...


<img src="image.png" onerror="alert('Your picture doesn\'t exist!');" />


By nonono you mean there's no way to validate an image url through a form textfield first before an attempted display on screen?

Maybe I should have a passthrough page and validate the attempted submission on the next page before committing an entry so the image can actually attempt to display first? And then maybe I could disable the submit button on the second page if an onerror is thrown for the image and have them go back to the first form for re-entry.

I'll just do the message to inform the user at least for now.

monaya
02-27-2009, 02:43 PM
Nonono...


<img src="image.png" onerror="alert('Your picture doesn\'t exist!');" />


Also the code above did not work correctly, but this one is perfect:

<script type="text/javascript">
var newImage = new Image();
newImage.src = "image.png";
newImage.onerror = function(){
alert("Your picture doesn't exist. :(");
};
</script>

Nile
02-27-2009, 09:48 PM
Try this:


<script type="text/javascript">
var validateImg = function(form){
var validate = new Image();
validate.src = form.elements["imageURL"].value;
validate.onerror = function(){ alert("Bad Image!"); };
};
</script>
<form onsubmit="validateImg(this); return false;">
<input type="text" name="imageURL" /><input type="submit" value="Validate!" />
</form>

monaya
02-27-2009, 10:31 PM
That's great. But right now its not submitting the form if the image does validate properly.

Also is there a way to limit image widths and heights or is that way complicated?

monaya
02-28-2009, 02:11 PM
I tried using return true;

it still doesnt submit the form if the image validates properly. It just ignores it.

jscheuer1
02-28-2009, 06:00 PM
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript">
function validateImg(form){
if(validateImg.loaded){
validateImg.loaded = false;
return true;
}
form.elements.sub.disabled = true;
if(validateImg.obj[form.elements["imageURL"].value + '_$_attempted']){
if(!confirm(form.elements["imageURL"].value + ' has been attempted before and failed.\n' +
'continue anyway?')){
form.elements["imageURL"].value = '';
return form.elements.sub.disabled = false;
}
else validateImg.obj[form.elements["imageURL"].value] = false;
}
if(!validateImg.obj[form.elements["imageURL"].value]){
validateImg.obj[form.elements["imageURL"].value] = true;
var validate = new Image();
validate.onload = function(){
validateImg.loaded = true;
validateImg.obj[form.elements["imageURL"].value] = form.elements.sub.disabled = false;
form.submit();
};
validate.onerror = function(){
alert("Bad Image!");
form.elements.sub.disabled = validateImg.loaded = false;
validateImg.obj[form.elements["imageURL"].value + '_$_attempted'] = true;
};
validateImg.loaded = false;
validate.src = form.elements["imageURL"].value;
}
return false;
}
validateImg.obj = [];
</script>
</head>
<body>
<form action="#" onsubmit="return validateImg(this);">
<div>
<input type="text" name="imageURL"><input name="sub" type="submit" value="Validate!">
</div>
</form>
</body>
</html>

monaya
02-28-2009, 06:20 PM
OK. That's pretty darn nice. I love your special touch about picking up second attempts. I might want to still disallow allowing it go through however. But I guess its a good idea in case the script fails to authenticate properly as well!

jscheuer1
02-28-2009, 07:16 PM
My thinking was that there is always a possibility that the image was only temporarily unavailable due to network traffic or whatever. If this is being used along with users uploading images, then perhaps the upload hadn't finished.

Most reasonable folks won't try too many times with a bad image, and it takes minimal server side resources anyway (depending upon what URL is entered, the server may not even need to get involved, and a 404 or other error is generally very low overhead), it is the user's browser that attempts to load the image.

I felt that there was no harm in allowing repeated validation of good images (they should now be cached on the user end anyway, so not affect the server much), but depending upon what this is used for, that could/should be changed.

For first time and previously good images, it currently only checks to see if the image is being checked, so as not to continually try to load it if it is already in the process of being loaded.

Once submitted by the user, the submit button is disabled until some result is determined.

Regardless of these various considerations, reloading the page can erase all stored information. A cookie could be used to maintain it, but with a lot of images, this could overflow the browser's cookie buffer, and the user may always clear or turn off cookies. If you want something more robust in that regard, you will need to use a server side language.

And, of course, with javascript disabled, the form will always submit, so if this is somehow crucial - again a server side language must be used.

monaya
02-28-2009, 10:45 PM
Yeah I agree. I'd rather not disallow the form just in case. It just allows users to submit an http hosted URL. I just don't want anything to go through. I'll also validate the image on the server side. Is there a way to put limits on the width and height? I think I can do this on the server side as well. I'll mess with it.

jscheuer1
03-01-2009, 12:14 AM
Getting the dimensions in javascript is easy once the image has loaded. Since we are already depending upon image load for approval, selecting for dimensions are minor additions (highlighted in two places, the two red 100's are the width and height limits respectively):


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript">
function validateImg(form){
if(validateImg.loaded){
validateImg.loaded = false;
return true;
}
form.elements.sub.disabled = true;
if(validateImg.obj[form.elements.imageURL.value + '_$_attempted']){
if(!confirm(form.elements.imageURL.value + ' has been attempted before and failed.\n' +
'continue anyway?')){
form.elements.imageURL.value = '';
return form.elements.sub.disabled = false;
}
else validateImg.obj[form.elements.imageURL.value] = false;
}
if(!validateImg.obj[form.elements.imageURL.value]){
validateImg.obj[form.elements.imageURL.value] = true;
var validate = new Image();
validate.onload = function(){
if(this.width > validateImg.wlimit || this.height > validateImg.hlimit){
alert(form.elements.imageURL.value + ' is too large!');
validateImg.obj[form.elements.imageURL.value + '_$_attempted'] = true;
form.elements.sub.disabled = false;
return;
}
validateImg.loaded = true;
validateImg.obj[form.elements.imageURL.value] = form.elements.sub.disabled = false;
form.submit();
};
validate.onerror = function(){
alert("Bad Image!");
form.elements.sub.disabled = validateImg.loaded = false;
validateImg.obj[form.elements.imageURL.value + '_$_attempted'] = true;
};
validateImg.loaded = false;
validate.src = form.elements.imageURL.value;
}
return false;
}
validateImg.obj = [];
validateImg.wlimit = 100;
validateImg.hlimit = 100;
</script>
</head>
<body>
<form action="#" onsubmit="return validateImg(this);">
<div>
<input type="text" name="imageURL"><input name="sub" type="submit" value="Validate!">
</div>
</form>
</body>
</html>

Note: I also changed all instances of:


["imageURL"]

to:


.imageURL

because they are equivalent in the code as written (this would only change if the name of that input could vary, and then a slightly different syntax would be required anyway) and the latter is slightly more efficient in this case.

monaya
03-05-2009, 03:29 PM
In Firefox, this code now seems to be blocking the submit even if the user clicks to continue anyway. It gives them the bad image alert no matter. Here's my code:


function validateImg(form){
document.getElementById('loadingmsg').innerHTML = "<img src='images/loading.gif' /> Validating... ";

if(validateImg.loaded){
validateImg.loaded = false;
return true;
}
form.elements.sub.disabled = true;
if(validateImg.obj[form.elements["externalthumb"].value + '_$_attempted']){
if(!confirm(form.elements["externalthumb"].value + ' has been attempted before and failed.\n' +
'continue anyway?')){
form.elements["externalthumb"].value = '';
return form.elements.sub.disabled = false;
}
else validateImg.obj[form.elements["externalthumb"].value] = false;
}
if(!validateImg.obj[form.elements["externalthumb"].value]){
validateImg.obj[form.elements["externalthumb"].value] = true;
var validate = new Image();
validate.onload = function(){
validateImg.loaded = true;
validateImg.obj[form.elements["externalthumb"].value] = form.elements.sub.disabled = false;
form.submit()
};
validate.onerror = function(){
alert("The URL to your thumbnail doesn't exist!");
document.getElementById('loadingmsg').innerHTML = "";
form.elements.sub.disabled = validateImg.loaded = false;
validateImg.obj[form.elements["externalthumb"].value + '_$_attempted'] = true;
};
validateImg.loaded = false;
validate.src = form.elements["externalthumb"].value;
}
return false;
}
validateImg.obj = [];


<input name="sub" type="submit" id="sub" value="upload embed code" onclick="this.disabled = disabled;"/>

jscheuer1
03-05-2009, 04:04 PM
Then go back to the code as shown previously. It was written and tested in FF, then checked in IE, Opera.

One thing I can tell you though, this was designed with a live URL for the image in mind, not a local one. I don't know about a text input, but with a file input (I was playing with the code a bit), FF would only show files in the same folder as the page. This is due to security measures of that browser, Opera was the same.

monaya
03-05-2009, 04:17 PM
Hmm. I'm pretty sure that was the original code. Let me double check.

monaya
03-05-2009, 05:06 PM
Then go back to the code as shown previously. It was written and tested in FF, then checked in IE, Opera.
One thing I can tell you though, this was designed with a live URL for the image in mind, not a local one.

yes I'm only concerned about a live url.

jscheuer1 please double check I tried using the original code and I see the same problem in Firefox and Safari. It just keeps saying bad image after clicking OK. I guess the code that checks for the image seems to always execute.

I don't know about IE because its not installed on the mac.

monaya
03-05-2009, 05:19 PM
Also after upgrading to Firefox 3.0.7, buttons that are disabled are never reenabled through javascript, although there are no problems with Safari and IE.

once you disable like:

form.elements.sub.disabled = true;

the following does not re-enable:

form.elements.sub.disabled = false;

I love Firefox, but it does some quirky things with javascipt now I'm realizing. Pretty annoying not to be able to re-enable a button after a failed authentication.

monaya
03-05-2009, 05:38 PM
Another bug I found is that when you do get the prompt to CANCEL or CONTINUE ANYWAY, and click CANCEL, the submit button no longer submits the form. This happens in IE too.

jscheuer1
03-05-2009, 05:41 PM
None of that is happening here, I just upgraded to FF 3.0.7. Here is my current working code:


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript">
function validateImg(form){
if(validateImg.loaded){
validateImg.loaded = false;
return true;
}
form.elements.sub.disabled = true;
if(validateImg.obj[form.elements.imageURL.value + '_$_attempted']){
if(!confirm(form.elements.imageURL.value + ' has been attempted before and failed.\n' +
'continue anyway?')){
form.elements.imageURL.value = '';
return form.elements.sub.disabled = false;
}
else validateImg.obj[form.elements.imageURL.value] = false;
}
if(!validateImg.obj[form.elements.imageURL.value]){
validateImg.obj[form.elements.imageURL.value] = true;
var validate = new Image();
validate.onload = function(){
if(this.width > validateImg.wlimit || this.height > validateImg.hlimit){
alert(form.elements.imageURL.value + ' is too large!');
validateImg.obj[form.elements.imageURL.value + '_$_attempted'] = true;
form.elements.sub.disabled = false;
return;
}
validateImg.loaded = true;
validateImg.obj[form.elements.imageURL.value] = form.elements.sub.disabled = false;
form.submit();
};
validate.onerror = function(){
alert('Bad Image!');
form.elements.sub.disabled = validateImg.loaded = false;
validateImg.obj[form.elements.imageURL.value + '_$_attempted'] = true;
};
validateImg.loaded = false;
validate.src = form.elements.imageURL.value;
}
return false;
}
validateImg.obj = {};
validateImg.wlimit = 1500;
validateImg.hlimit = 1500;
</script>
</head>
<body>
<form action="#" onsubmit="return validateImg(this);">
<div>
<input type="text" name="imageURL"><input name="sub" type="submit" value="Validate!">
</div>
</form>
</body>
</html>

monaya
03-05-2009, 06:05 PM
None of that is happening here, I just upgraded to FF 3.0.7.

Hmm. Its still happening on my end. Would you mind putting your code up live and let me test it on my browsers like before.
Here are the bugs I found.

Clicking CANCEL breaks the button in IE.

and in all browsers the code that verifies the image always runs no matter.

I'm going to put up a live page with the code and see what you get on your end.

jscheuer1
03-05-2009, 06:19 PM
http://home.comcast.net/~jscheuer1/side/image_form.htm

monaya
03-05-2009, 06:24 PM
Its weird now firefox seems to re-enable the button. The issue comes and goes. People probably think I'm nuts :)

But it's still always checking the URL and saying BAD IMAGE even when you click OK anyway on your page.

and here it is on my end. What are you getting here?
http://monaya.bravehost.com/javascriptfun/checkimage.htm

jscheuer1
03-06-2009, 02:34 PM
I'm just not getting those results here. Do you mean that if an image checks out as bad, then you upload an image to the 'bad' location and run again that even though the image is now good, it's still bad? If that's what you are talking about, we will need to 'bust the cache' on previously bad images. But I don't want to bother writing the code for that unless that's the problem. If that isn't the problem, what exactly do I have to do - step by step - and in what browser - to get mine to show this problem.

monaya
03-08-2009, 10:48 PM
I'm just not getting those results here.
In the original code you said that if a user attempts to enter a Live image URL that is not real twice, they get to submit the form anyway by hitting OK but thats not happening?

This is in Firefox 3.0.7
I tried hitting Validate once entering nothing I get this:
http://screencast.com/t/6utHh7AYLFp

I tried again to try a second submission entering nothing again I get this:
http://screencast.com/t/raOcWjdxq

When you hit ok you get this again:
http://screencast.com/t/ng5Wydig

Then what's the point of giving the user a choice if it's still going to disallow a bad live url anyhow.

Same thing happens In Safari 3.2.1 but also the button just becomes forever disabled if nothing is entered.


Just little quirks I guess.

jscheuer1
03-09-2009, 02:03 PM
Well technically no, not quirks. But yes something quirky. Um, the behavior in FireFox is correct. What do you expect to happen? I mean, if you continue to enter a bad image, it isn't suddenly going to become good. However, if circumstances were to change and a URL that previously pointed to a bad or missing image now points to a valid image, then it would go through. I'm not sure why there is a problem in Safari with the validate button not returning to a clickable state. The easiest thing for that would be to add a reset button to the form:


<input type="reset" value="Reset" onclick="this.form.elements.sub.disabled=false;return true;">

However, Safari may just need to have a timeout used to enable it to make the validate button clickable again, in other words - things may just be happening too fast for Safari.

Now, forget about Safari for a moment, if there is something else you would want it to do on the second attempt of a bad image, that could probably be arranged, but I would need to know specifically what that might be.

Added Later:

I figured out the problem in Safari. If the image object source (form.elements.imageURL.value) is blank neither the onload nor the onerror functions fire. I 'fixed' that by forcing the onerror function to fire in that case. Be sure to refresh the page before trying a blank submission again in Safari. Of course, other behavior could be substituted. Perhaps the best thing in that case would be to not submit and to re-enable the validate button. It's really just a judgement call.