Forum Moderators: open

Message Too Old, No Replies

Global Variables in JS behave funny

global variables

         

mongoloid001

7:36 pm on Jul 4, 2003 (gmt 0)

10+ Year Member



I had a global variable in

<script>
var global = null;
document.write("<input type='img' src='n.gi' onerror='global=true;'>");
if (global== null) {
alert("img found");
}
else {
alert("img not found");
}
</script>

the variable 'global' is always null regardless if img is found or not. But if I put another alert() statement before the if statement, everything works fine.

I discarded the above code, but if anyone can explain the above strange behaviour, I would certailnly appreciate it.

Thanks!

claus

11:19 pm on Jul 4, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



There's a couple of things (assuming this is javascript and not VBscript):

First, your "global" variable is not a global variable, it's a local variable by the name "global".

Second, it's not always a good idea to use the expression "null" unless you mean exactly that (it is not the same as zero)

Third, the onError event handler clings to a) window, and b) image. When used with "window" it's all lower case, and when used with "image" the E is in upper case. It is not intended for "input".

Forth, onError can be one of these:

a) null

b) the name of a javascript function that returns true

c) a variable that contains null or a property that contains null

- you can not use it for anything that's not a, b, or c.

Here's a rewrite:


<script type="text/javascript">
var global = 0;

function doErrorMessage() {
alert("img not found");
global = 1;
}

document.write("<img src='n.gi' onError='doErrorMessage()'>");

if (global != 1) {
alert("img found");
}
</script>

<edit>typos</edit>

[edited by: claus at 11:36 pm (utc) on July 4, 2003]

devvie

11:34 pm on Jul 4, 2003 (gmt 0)

10+ Year Member



Hi mongoloid001,

The image onError does not work if you use the <input type='img'>. Only 'the real deal' does: <img> tag.

Also you must call a function in your onError for the code to work.

Furthermore, why document.write HTML when ordinary HTML works as well AND is shorter in this case? AND also non-javascript browsers wil show, or try to show your image.

This certainly does do the job and it's a lot shorter:


<script language="JavaScript">
function gofish() { alert("img not found") }
</script>

<img src="n.gi" onError="JavaScript: gofish()">


(Tested OK in IE6, NN7, NN6.2, NN4.7 and Op7)

This way there's no need for a 'global' variable or an "img found" alert (obviously the reader will notice it if the image is found).

<John DeVie />

gph

12:31 am on Jul 5, 2003 (gmt 0)

10+ Year Member



It's a timing thing. The browser is doc writing the image then a split second later going through the if statement. The onerror event is firing after the if statement has been read.

That's why an alert before the if statement works, it gives it time to fire the onerror event before you click ok.

Does that make any sense?

ricfink

5:34 am on Jul 5, 2003 (gmt 0)

10+ Year Member



Hmm.. learned a lot from this one. Didn't know onerror even existed.
However, I disagree with Claus: the variable 'global' in the original example IS a global variable by my understanding of the word.
Global meaning it's not contained within a function and therefore is "seen" by and available to all functions on the page.

claus

2:50 pm on Jul 5, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



ricfink, you're right and i was wrong. Aplologies to all.

The variable "global" in post #1 is a global variable. It is global because it is not declared or initialized inside a function.

The reason for my mistake is the "var" keyword, and perhaps i was a bit tired as well. I must somehow have convinced myself that the "var global" statement was inside a function when, in fact, it was not.

The thing is, that the "var" is important. If you declare a variable inside a function using the "var" it becomes local. On the other hand, if you declare a variable inside a function without the var, it becomes global. To illustrate, i found this snippet of code somewhere in a js-tutorial [webdevelopersnotes.com]:

var a = 10;

disp_a();

function disp_a()
{
var a = 20;
alert("Value of 'a' inside the function " + a);
}

alert("Value of 'a' outside the function " + a);

/claus

ricfink

7:24 pm on Jul 5, 2003 (gmt 0)

10+ Year Member



Post in revision.....

[edited by: ricfink at 7:56 pm (utc) on July 5, 2003]

claus

7:37 pm on Jul 5, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



a bit confusing, yes, but i get it. Still, i will not bend until proven wrong ;)

ricfink, i took your example and pasted it directly into an empty html document (including the buttons), then i opened it in a browser.

The values of "a" were

Inside: 20
Outside: 10

- just as i thought they would be. Meaning: the local variable "a" and the global variable "a" coexist. Even though they have the same name, they have different values.

/claus

<edit>i did not put // before the function call, it worked as it should</edit>
<edit2>even with the // the two vars are still different</edit2>

ricfink

8:05 pm on Jul 5, 2003 (gmt 0)

10+ Year Member



Yeah, Claus. No matter how many times I say to myself "do a test page first, do a test page first" I still put my foot in my mouth! Getting it wrong and making a fool out of myself is a sub-specialty of mine.

I misunderstood the fine distinction you were making between referring to the global variable within the function and re-declaring it using var within the function.

So let's leave it at this for any javascript newbies who stumble upon this thread looking for answers:

Variables declared using var (var = x) OUTSIDE a function are global.
If you want to use the same name for a variable within a function (a practice to be avoided), and keep that variable local to the function so it doesn't change the value of the global variable of the same name, then re-declare the variable within the function using var.

Howzat?

claus

9:12 pm on Jul 5, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



*lol* ricfink i know all about it - i was the one who started by seeing a function that wasn't there ;)

I'll subscribe to your summary anytime!

Regarding the original post, devvie and gph also have some good points above.

Oh.. and: Welcome to WebmasterWorld devvie :)

/claus

<edit>added the subscribe part</edit>

mongoloid001

6:59 pm on Jul 8, 2003 (gmt 0)

10+ Year Member



Technically, I don't think my logic was wrong in the original code, ugly as it was:). So I guess I would have to agree with the following explaination by gph:


It's a timing thing. The browser is doc writing the image then a split second later going through the if statement. The onerror event is firing after the if statement has been read.

That's why an alert before the if statement works, it gives it time to fire the onerror event before you click ok.

Does that make any sense?

But this means that you cannot set up any global variable in onload(). Or at least, you cannot rely on it...

BTW, you guys got lost somewhere and forgot about my question:).

gph

6:27 am on Jul 9, 2003 (gmt 0)

10+ Year Member



If you mean the image onload no, not if it can't be found. You can set up a function as devvie described for onerror and change your global var in it.

HTML:

<input type="image" src="n.gi" onerror="img_error()">

js:

var img_found = true

function img_error() {
img_found = false
}

If you just want to swap the image if there is an error you don't need a global var or a function.

<input type="image" src="a.gif" onerror="this.src='b.gif'">

If none of this is what you're looking for please explain further what you're trying to do.

mongoloid001

5:13 pm on Jul 9, 2003 (gmt 0)

10+ Year Member



My question is why, in the if() statement, the global variable is still null even though in onerror() I set it to true? But if I put an alert in between onerror() and the if() statement, the global variable is set to true according to the execution sequence?

It's like a delay setting varialbe problem. And I am seeking a reasonable explaination.

Thanks!

gph

1:20 am on Jul 10, 2003 (gmt 0)

10+ Year Member



I took your second post to mean you understood what I was saying. Maybe this will help. I commented out your alerts so you can see the order that things are occurring.

<html>
<head>
<title></title>
</head>
<body>
<div id="output"></div>
<script>
var OutPut = document.getElementById('output')

function write_error() {
global = true
OutPut.innerHTML += 'onerror event'
}

var global = null
document.write("<input type='image' src='n.gi' onerror='write_error()'>")

OutPut.innerHTML += 'after document.write<br>'

if (global== null) {
//alert("img found");
}
else {
//alert("img not found");
}

OutPut.innerHTML += 'after if statement<br>'
</script>
</body>
</html>

amznVibe

2:58 am on Jul 10, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Um, isn't it WAY simpler than all this? In most browsers the image doesn't exist until its fully loaded and the <body> is closed. It will always return false if you test before then. Why not test this with a <body onLoad="..."> statement to be sure...