Adding events dynamically

D

David

I have a one-line script to add an onunload event handler to the body of the
document. The script is as follows:

document.getElementsByTagName("BODY")[0].onunload=function s() {alert("s")}

Now obviously, I put the alert("s") part in for debugging purposes, just to
make sure the error wasn't in any code I was going to be running. This line
works just fine in IE6 but in Firefox it doesn't. However, if I replace
that line with the following:

document.getElementsByTagName("BODY")[0].onunload=s

and I make a function called s, then it works just fine in both browsers.
So, I guess I'm just curious as to whether the first line is an IE-only
syntax or what.
 
D

David

David said:
I have a one-line script to add an onunload event handler to the body of
the document. The script is as follows:

document.getElementsByTagName("BODY")[0].onunload=function s()
{alert("s")}

Now obviously, I put the alert("s") part in for debugging purposes, just
to make sure the error wasn't in any code I was going to be running. This
line works just fine in IE6 but in Firefox it doesn't. However, if I
replace that line with the following:

document.getElementsByTagName("BODY")[0].onunload=s

and I make a function called s, then it works just fine in both browsers.
So, I guess I'm just curious as to whether the first line is an IE-only
syntax or what.

That second script line should read as follows

document.getElementsByTagName("BODY")[0].onunload=s()

with the parentheses after s.
 
R

RobG

David said:
I have a one-line script to add an onunload event handler to the body of
the document. The script is as follows:

document.getElementsByTagName("BODY")[0].onunload=function s()
{alert("s")}


That particular variant will pester IE users only. Try:

window.onunload = function () { alert('s'); };

or

function s (){
alert('s');
}

window.onunload = s;

Both of which will annoy users of IE also.

window.onunload is DOM level 0 and not part of the W3 spec. Mozilla
seems to allow the body onunload to be added dynamically but doesn't
execute it when the page unloads. Where onunload exists in the source
HTML, it seems to work as expected.

Adding window.onunload dynamically seems to work in Mozilla and IE.

<URL:http://www.mozilla.org/docs/dom/domref/dom_window_ref75.html>

The use of onunload is not encouraged for general web pages, its
principal use initially having been to create 'pop-up hell'. I hope
your intentions are more honourable.

[...]
 
A

ASM

David said:
I have a one-line script to add an onunload event handler to the body of
the document. The script is as follows:

document.getElementsByTagName("BODY")[0].onunload=function s()
{alert("s")}

on a single line :

document.getElementsByTagName("BODY")[0].onunload=Function('alert(\'s\')');

variante :

function s() { alert('s'); }
document.getElementsByTagName("BODY")[0].onunload = s;
 
D

David

RobG said:
Try:

window.onunload = function () { alert('s'); };

or

function s (){
alert('s');
}

window.onunload = s;

Both of which will annoy users of IE also.

Well, strangely enough, it is not IE which is causing me the problems, as it
works in IE in both ways stated above, however, in Firefox, the only way I
can get the function to actually happen when the onunload event occurs on
the browser is to use the following.

function s (){
alert('s');
}

window.onunload = s();

The different being that the function name MUST have parentheses after it
for that function to get run onunload. With this format, IE doesn't work
correctly, which it shouldn't. So, without browser-sniffing, I can't seem
to figure a way to get it to work.
window.onunload is DOM level 0 and not part of the W3 spec. Mozilla seems
to allow the body onunload to be added dynamically but doesn't execute it
when the page unloads. Where onunload exists in the source HTML, it seems
to work as expected.

Adding window.onunload dynamically seems to work in Mozilla and IE.

<URL:http://www.mozilla.org/docs/dom/domref/dom_window_ref75.html>

IE seems to be honoring this syntax but I can't get Firefox to work any
other way than to have the parentheses following the function name, such as
window.onunload = funcRef()
The use of onunload is not encouraged for general web pages, its principal
use initially having been to create 'pop-up hell'. I hope your intentions
are more honourable.

To explain to you a bit more of what I'm trying to do, I have created a
shopping-cart style application, and when the user wants to view the
shopping cart, it opens a new window with the shopping cart information in
it. If the user changes web sites or refreshes the page, I do not want the
shopping cart window to stay open, so I want to put an onunload event on the
BODY element which will automatically close the shopping cart window if it
is open. The reason I must set this dynamically is that this may get
integrated into an HTML template, which means I don't have any control over
the HTML template and I can't add/change the template (except at runtime),
so any stylesheet link tags or script file dependencies must be added at
runtime. In addition, I must add my onunload event to the BODY tag
dynamically since I don't have control over the HTML source. The only way I
could possibly put a static onunload event in the HTML would be to have my
PHP code automatically edit the templates to include the onunload event in
there, but I would prefer to avoid that option for obvious reasons.

Now, another problem I discovered with Firefox is that when I do use the
obj.onunload=funcdef() syntax, then I can get an alert to display onunload.
However, when I replace the alert with my desired code, I am getting an
error (which I do not get in IE). What I am doing is checking to see if my
windowhandle variable exists and if it does, I am using the statement
winDVDCart.close(), where winDVDCart is my window handle. In Firefox I am
getting the error "winDVDCart has no properties" as if my handle to that
window object has already been cleared before this event code ran. But if I
actually DO put the onunload="..." in the HTML on the BODY tag, it will
close the window without a problem. Same code, same function, just defined
statically instead of dynamically.

It appears that Firefox has it's own share of things that aren't exactly
working as defined so if anyone could give me an idea of what to do here I
would greatly appreciate it. I haven't tried the window.addEventListener()
method yet but, once again, if I did that I would have to use
browser-sniffing because IE doesn't yet support the addEventListener()
method. If someone would like more information or explanation on what I'm
trying to do I'd be more than happy to explain and demonstrate with some
real code clips. Thanks for the help so far.

David
 
R

RobG

David said:
Well, strangely enough, it is not IE which is causing me the problems, as it
works in IE in both ways stated above, however, in Firefox, the only way I
can get the function to actually happen when the onunload event occurs on
the browser is to use the following.

function s (){
alert('s');
}

window.onunload = s();

Using Firefox 1.0.4 on Windows XP it works exactly as I posted.

The code posted by ASM below does not (it adds the script to the body
onunload event handler but it isn't actually run on unload).

[...]
It appears that Firefox has it's own share of things that aren't exactly
working as defined so if anyone could give me an idea of what to do here I
would greatly appreciate it. I haven't tried the window.addEventListener()
method yet but, once again, if I did that I would have to use
browser-sniffing because IE doesn't yet support the addEventListener()
method.

No browser-sniffing required, use feature detection. IE uses
'attachEvent', search through the newsgroup for examples - there's one here:

<URL:http://groups-beta.google.com/group...ddEventListener&rnum=4&hl=en#4fe5cb59dc00cbeb>


But I have no idea if that will fix your issue.
method. If someone would like more information or explanation on what I'm
trying to do I'd be more than happy to explain and demonstrate with some
real code clips. Thanks for the help so far.

You may try using setInterval to check for window.opener. If not
present, close the pop-up. The script below sets a variable to false
when loaded, then sets it to true when the child is opened.

The child checks every second to see if it can still access the variable
in the opener. If not, it closes itself - you may want to shorten the
time interval. Try..catch is used 'cos trying to access the parent once
it's moved to another domain will likely cause the script to fail and
may cause a security message to appear for your users - not nice.

Not bullet proof or even fool proof, but likely to suit if closing the
window is not critical.


Demo only of course:


<script type="text/javascript">

var stillHere= false;

function popWin () {

stillHere = true;

var cont = [
'<html><head><title>disappearing window</title>',
'<script type="text/javascript">',
'function checkOpener() {',
' var stayOpen = false;',
' try {',
' stayOpen = window.opener.stillHere;',
' } catch (e) {};',
' if ( ! stayOpen ) self.close();',
'}',
' var timer = setInterval( "checkOpener()", 1000);',
'<\/script></head><body>',
'<input type="button" value="checkOpener" onclick="',
' checkOpener();"></body></html>'
];
pWin = window.open('','POPwin','');
pWin.document.open();
pWin.document.write( cont.join('') );
pWin.document.close();

}
</script>
 
V

VK

Event handler assignments require *function reference* as its argument.

This reference can be provided in three and only ways in JavaScript:

1) By referencing to an existing function:
object.onevent = functionName;
*without parenthesis*, else you're getting instead of function
reference the literal defining function body;

2) By attaching an *anonymous* function:
object.onevent = function(args) { /* statements */ }

3) By referencing newly created Function:
object.onevent = new Function(arg1, arg2, arg3, body);

This is all. Other variants may work or not on different browsers. It
may happen because creators knew in advance that by the many-years
tradition users will prefer to invent their own language rather than
learn the docs. So they tried to predict (with different level of
success) what "improvement" and "extentions" most probably the
interpreter may encounter. And they tried to learn it to translate from
DavidScript, JoeScript and MikeScript back to JavaScript. Again,
sometimes they got a success, but sometimes the user fantasy overcomes
any predictions. :)
 
A

askMe

Why can't you put the onunload in the main template? You say for
obvious reasons, but I do not see any obvious reason for not putting
the onunload there. If onunload is put on the parent, the child can be
controlled. The child cannot always control the parent.

The only other thing I can think of is to use the setinterval as
someone else has already posted, but, that, too, is a no-no.

http://www.askblax.com
 
V

VK

All above stated refers to the statements within the <script> body.

*Some* (but not all) events can be attached to intrinsic handlers
within HTML elements, and *then* you have to use parenthesis:

<body onunload="myFunction()">
 
D

David

RobG said:
Using Firefox 1.0.4 on Windows XP it works exactly as I posted.

Hmm, I'm using Firefox 1.0.5 on Windows XP SP2 and it's not working right, I
can't seem to find any bugs posted on bugzilla about it either. I even took
it all out of the page I'm working in, just to make sure there's nothing
else affecting it, and I wrote the following little HTML page to test it in
Firefox.

<HTML>
<BODY>
<script>
document.getElementsByTagName("BODY")[0].onunload=unloadBody
function unloadBody()
{
alert("here")
}
</script>
</BODY>
</HTML>

Works in IE6, doesn't work in Firefox 1.0.5. However, the moment I put ()
after the funcdef like this

document.getElementsByTagName("BODY")[0].onunload=unloadBody()

it works in Firefox and not in IE. Seems like Firefox is broken to me
unless a spec has been changed somewhere that I am not aware of.
You may try using setInterval to check for window.opener. If not present,
close the pop-up. The script below sets a variable to false when loaded,
then sets it to true when the child is opened.

The child checks every second to see if it can still access the variable
in the opener. If not, it closes itself - you may want to shorten the time
interval. Try..catch is used 'cos trying to access the parent once it's
moved to another domain will likely cause the script to fail and may cause
a security message to appear for your users - not nice.

Not bullet proof or even fool proof, but likely to suit if closing the
window is not critical.


Demo only of course:

Thanks, I used this approach and, though it's not necessarily the best way
of doing things, it will work well enough for what I'm trying to accomplish.
I might try playing around with the attachEvent and addEventListener way of
doing things as well to see if that works. Thanks again for your help!
 
R

RobG

David wrote:
[...]
Hmm, I'm using Firefox 1.0.5 on Windows XP SP2 and it's not working right, I
can't seem to find any bugs posted on bugzilla about it either. I even took
it all out of the page I'm working in, just to make sure there's nothing
else affecting it, and I wrote the following little HTML page to test it in
Firefox.

<HTML>
<BODY>
<script>
document.getElementsByTagName("BODY")[0].onunload=unloadBody
function unloadBody()
{
alert("here")
}
</script>
</BODY>
</HTML>

Works in IE6, doesn't work in Firefox 1.0.5. However, the moment I put ()
after the funcdef like this

document.getElementsByTagName("BODY")[0].onunload=unloadBody()

it works in Firefox and not in IE. Seems like Firefox is broken to me
unless a spec has been changed somewhere that I am not aware of.

That shouldn't work in Firefox, it should execute unloadBody() and
assign the result to the body onunload event. If that's not happening,
then yes, it's a bug in Firefox.

Guess I'll not 'upgrade' to 1.0.5 just yet ;-p

[...]
Thanks, I used this approach and, though it's not necessarily the best way
of doing things, it will work well enough for what I'm trying to accomplish.
I might try playing around with the attachEvent and addEventListener way of
doing things as well to see if that works. Thanks again for your help!

You didn't say if the anonymous function version worked or not:

window.onunload = function () { alert('hi'); };

Your original version had an 's' after function.
 
D

David

Rob said:
You didn't say if the anonymous function version worked or not:

window.onunload = function () { alert('hi'); };

Your original version had an 's' after function.

The anonymous function version did not work in Firefox.
 
L

Lee

David said:
Hmm, I'm using Firefox 1.0.5 on Windows XP SP2 and it's not working right, I
can't seem to find any bugs posted on bugzilla about it either. I even took
it all out of the page I'm working in, just to make sure there's nothing
else affecting it, and I wrote the following little HTML page to test it in
Firefox.

The following was tested in Firefox 1.0.5 in Windows XP SP2 and
works just fine. Anytime you put parentheses after a function
reference, the function is invoked immediately, in Firefox just
like any other browser:

<html>
<head>
<script type="text/javascript">
function s() {
alert("s");
}
window.onunload=s;
</script>
</head>
<body>
<p>This is the body</p>
</body>
</html>
 
D

David

Lee said:
The following was tested in Firefox 1.0.5 in Windows XP SP2 and
works just fine. Anytime you put parentheses after a function
reference, the function is invoked immediately, in Firefox just
like any other browser:

<html>
<head>
<script type="text/javascript">
function s() {
alert("s");
}
window.onunload=s;
</script>
</head>
<body>
<p>This is the body</p>
</body>
</html>

Works fine for me too. Try replacing the window.onunload with
document.getElementsByTagName("BODY")[0].onunload
 
L

Lee

David said:
The following was tested in Firefox 1.0.5 in Windows XP SP2 and
works just fine. Anytime you put parentheses after a function
reference, the function is invoked immediately, in Firefox just
like any other browser:

<html>
<head>
<script type="text/javascript">
function s() {
alert("s");
}
window.onunload=s;
</script>
</head>
<body>
<p>This is the body</p>
</body>
</html>

Works fine for me too. Try replacing the window.onunload with
document.getElementsByTagName("BODY")[0].onunload

Of course that won't work. At the time that it executes, there
is no "body".
 
D

David

Lee said:
David said:
The following was tested in Firefox 1.0.5 in Windows XP SP2 and
works just fine. Anytime you put parentheses after a function
reference, the function is invoked immediately, in Firefox just
like any other browser:

<html>
<head>
<script type="text/javascript">
function s() {
alert("s");
}
window.onunload=s;
</script>
</head>
<body>
<p>This is the body</p>
</body>
</html>

Works fine for me too. Try replacing the window.onunload with
document.getElementsByTagName("BODY")[0].onunload

Of course that won't work. At the time that it executes, there
is no "body".

Sorry, that was an accident and I didn't mean to write it that way, but it
won't work if you put the script tag AFTER or IN the body tag either.
 
L

Lee

David said:
Lee said:
David said:
Lee wrote:
The following was tested in Firefox 1.0.5 in Windows XP SP2 and
works just fine. Anytime you put parentheses after a function
reference, the function is invoked immediately, in Firefox just
like any other browser:

<html>
<head>
<script type="text/javascript">
function s() {
alert("s");
}
window.onunload=s;
</script>
</head>
<body>
<p>This is the body</p>
</body>
</html>

Works fine for me too. Try replacing the window.onunload with
document.getElementsByTagName("BODY")[0].onunload

Of course that won't work. At the time that it executes, there
is no "body".

Sorry, that was an accident and I didn't mean to write it that way, but it
won't work if you put the script tag AFTER or IN the body tag either.

Script should never appear after the body.
It should be in the head or in the body.
I wouldn't expect code within the definition of the body to
be able to access be able to reference the body, either.
Why not just use window.onunload? The event handler is an
attribute of the window object, after all.
 
R

RobG

David said:
Sorry, that was an accident and I didn't mean to write it that way, but it
won't work if you put the script tag AFTER or IN the body tag either.

Lee is absolutely right, I didn't realise that was how you were testing.
The following example adds an anonymous function to the
window.onunload, adding it to document.body.onunload didn't work in
Firefox (but did in IE).

Click the button to show the pop-up, reload the page and the child closes.


<html><head><title> close window test </title>
<script type="text/javascript">

function popWin() {

zWin = window.open('','zWin','width=550,height=200');

window.onunload = function () {
if ( zWin ) zWin.window.close();
};
}
</script>
</head><body>
<input type="button" value="Click to display window"
onclick="popWin();">
</body></html>
 
D

David

Thanks to both of you, I didn't realize that the window.onunload fired at
the same times as the body onunload (or do they always fire at the same
time?). It appears there is a bug report already at
https://bugzilla.mozilla.org/show_bug.cgi?id=52440


regarding exactly the issue of not being able to assign an onunload event
handler to the body dynamically. Anyways, thanks for the help and insight
to all that gave input.

David
 
G

Grant Wagner

David said:
Thanks to both of you, I didn't realize that the window.onunload fired
at the same times as the body onunload (or do they always fire at the
same time?). It appears there is a bug report already at
https://bugzilla.mozilla.org/show_bug.cgi?id=52440

There is no body onunload event. Assigning a function to an attribute of
the body tag called onunload sets window.onunload (in IE only). This can
be confirmed with the following code:

<script type="text/javascript">
window.onload = test;

function test() {
document.getElementsByTagName("BODY")[0].onunload = s;
alert(window.onunload);
}

function s() {
alert('unload');
}
</script>

Interestingly enough, in Opera 8.01, window.onunload is undefined after
setting the onunload attribute of the body tag, but the onunload event
fires correctly when unloading a page.
regarding exactly the issue of not being able to assign an onunload
event handler to the body dynamically. Anyways, thanks for the help
and insight to all that gave input.

Since <body onunload="..."> (or
document.getElementsByTagName("BODY")[0].onunload = ...;) sets (or
should set) window.onunload, there is never any reason to actually set
the onunload attribute of the body tag dynamically. While dynamically
setting the onload attribute of the body tag should work, the fact that
it doesn't should probably be a low-priority issue for the Mozilla team.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top