467,166 Members | 1,133 Online
Bytes | Developer Community
Ask Question

Home New Posts Topics Members FAQ

Post your question to a community of 467,166 developers. It's quick & easy.

Adding events dynamically

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.
Jul 23 '05 #1
  • viewed: 12550
Share:
20 Replies
"David" <dk****@hotmail.com> wrote in message
news:Ls********************@comcast.com...
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.
Jul 23 '05 #2

No, the 1st example is indeed mistaken and IE is incorrectly passing the
function object, should be:

obj.onunload=function(){ ...... } // or
obj.onunload=FUNCTIONHEREWITHNOARGS;

You can also use DOM obj.addEventListener() or for IE obj.attachEvent();

Danny

--
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Jul 23 '05 #3
David wrote:
"David" <dk****@hotmail.com> wrote in message
news:Ls********************@comcast.com...
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.

[...]
--
Rob
Jul 23 '05 #4
ASM
David wrote:
"David" <dk****@hotmail.com> wrote in message
news:Ls********************@comcast.com...
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;

--
Stephane Moriaux et son [moins] vieux Mac
Jul 23 '05 #5
"RobG" <rg***@iinet.net.auau> wrote in message
news:_j***************@news.optus.net.au...
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
Jul 23 '05 #6
David wrote:
"RobG" <rg***@iinet.net.auau> wrote in message
news:_j***************@news.optus.net.au...
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();


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/comp.lang.javascript/browse_frm/thread/d80acdb098819d24/4fe5cb59dc00cbeb?q=addEventListener&rnum=4&hl=en#4 fe5cb59dc00cbeb>
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>

--
Rob
Jul 23 '05 #7
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. :-)

Jul 23 '05 #8

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

Jul 23 '05 #9
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()">

Jul 23 '05 #10
RobG wrote:
David wrote:
"RobG" <rg***@iinet.net.auau> wrote in message
news:_j***************@news.optus.net.au...
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();


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!
Jul 23 '05 #11
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.

--
Rob
Jul 23 '05 #12
Rob G wrote:
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.
Jul 23 '05 #13
Lee
David said:

RobG wrote:
David wrote:
"RobG" <rg***@iinet.net.auau> wrote in message
news:_j***************@news.optus.net.au...

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();


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.


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>

Jul 23 '05 #14
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
Jul 23 '05 #15
Lee
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".

Jul 23 '05 #16

"Lee" <RE**************@cox.net> wrote in message
news:db********@drn.newsguy.com...
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.
Jul 23 '05 #17
Lee
David said:


"Lee" <RE**************@cox.net> wrote in message
news:db********@drn.newsguy.com...
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.

Jul 23 '05 #18
David wrote:

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>


--
Rob
Jul 23 '05 #19
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
Jul 23 '05 #20
"David" <dk****@hotmail.com> wrote in message
news:74********************@comcast.com...
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.

--
Grant Wagner <gw*****@agricoreunited.com>
comp.lang.javascript FAQ - http://jibbering.com/faq
Jul 23 '05 #21

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Oddball | last post: by
5 posts views Thread by Mark Rae | last post: by
11 posts views Thread by Neo Geshel | last post: by
3 posts views Thread by Bart Van Hemelen | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.