PDA

View Full Version : adding a onbeforeunload event to an existing onbeforeunload


FunkyORACLE
05-07-2009, 02:06 PM
Hi

I have an onbeforeunload event which works perfectly. However the application I am using creates html pages dynamically as part of creating these dynamically it allows the user to add onload/onbeforeunload events to the body tag for specific pages. It has a main template that it uses to produce some of the header/body of the page and populates the rest.

In the template I added a onbeforeunload event to the body tag which works perfectly except if the user has specified a onbeforeunload it just seems to ignore their onbeforeunload event.

Is there a way that I could append the js functions to the onbeforeunload event?

For example: If the page has a user specified onbeforeunload event then to add the js functions to the end of the existing onbeforeunload event thats being used in the template.

Any help much appreciated

adios
05-07-2009, 07:06 PM
function addListener(obj, evt, handler)
{
if (obj.addEventListener)
{
obj.addEventListener(evt, handler, false);
}
else if (obj.attachEvent)
{
obj.attachEvent('on' + evt, handler);
}
}

addListener(window, 'beforeunload', a_function);

Handlers assigned using these methods do not overwrite previous assignments, but simply add new ones. There are functions that specifically check the property involved (window.onbeforeunload, e.g.) and 'bundle' the old handler with the new; however, the above method is well-supported and works. Hopefully you can include it in that application.

Other route:
function addbeforeunloadEvent(func)
{
var oldonbeforeunload = window.onbeforeunload;
if (typeof window.onbeforeunload != 'function') {
window.onbeforeunload = func;
} else {
window.onbeforeunload = function() {
oldonbeforeunload();
func();
}
}
}

FunkyORACLE
05-08-2009, 03:23 PM
Thanks Adios, I'm now getting a JS error which I'm not to sure whats causing it on line 51.

This is what I have

<html lang="en-gb" xmlns:htmldb="http://htmldb.oracle.com">
<head>

<title>Home Page</title>

<script language="JavaScript" type="text/javascript">

function html_Submit_Progress(pRequest){

//Set Progress Options
var grayOptions = {};
var loadingOptions = {};
loadingOptions.msg = '...Loading...';
grayOut(grayOptions,loadingOptions);

html_ShowElement('AjaxLoading');
window.setTimeout('$x("wait").src = $x("wait").src', 100);

//doSubmit(pRequest);
}
//-->

//Some code taken from: http://www.hunlock.com/blogs/Snippets:_Howto_Grey-Out_The_Screen
function grayOut(grayOptions,loadingOptions) {
// Pass true to gray out screen, false to ungray
// options are optional. This is a JSON object with the following (optional) properties
// opacity:0-100 // Lower number = less grayout higher = more of a blackout
// zindex: # // HTML elements with a higher zindex appear on top of the gray out
// bgcolor: (#xxxxxx) // Standard RGB Hex color code
// grayOut(true, {'zindex':'50', 'bgcolor':'#0000FF', 'opacity':'70'});
// Because options is JSON opacity/zindex/bgcolor are all optional and can appear
// in any order. Pass only the properties you need to set.
var grayOptions = grayOptions || {};
var zindex = grayOptions.zindex || 10;
var opacity = grayOptions.opacity || 20;
var opaque = (opacity / 100);
var bgcolor = grayOptions.bgcolor || '#000000';
var dark=document.getElementById('darkenScreenObject');
if (!dark) {
// The dark layer doesn't exist, it's never been created. So we'll
// create it here and apply some basic styles.
// If you are getting errors in IE see: http://support.microsoft.com/default.aspx/kb/927917
var tbody = document.getElementsByTagName("body")[0];
var tnode = document.createElement('div'); // Create the layer.
tnode.style.position='absolute'; // Position absolutely
tnode.style.top='0px'; // In the top
tnode.style.left='0px'; // Left corner of the page
tnode.style.overflow='hidden'; // Try to avoid making scroll bars
tnode.style.display='none'; // Start out Hidden
tnode.id='darkenScreenObject'; // Name it so we can find it later
tbody.appendChild(tnode); // Add it to the web page
dark=document.getElementById('darkenScreenObject'); // Get the object.
}

// Calculate the page width and height
/* For this example want all if it off
if( document.body && ( document.body.scrollWidth || document.body.scrollHeight ) ) {
var pageWidth = document.body.scrollWidth+'px';
var pageHeight = document.body.scrollHeight+'px';
} else if( document.body.offsetWidth ) {
var pageWidth = document.body.offsetWidth+'px';
var pageHeight = document.body.offsetHeight+'px';
} else {
var pageWidth='100%';
var pageHeight='100%';
} */
//Always go with 100%
var pageWidth='100%';
var pageHeight='100%';

//set the shader to cover the entire page and make it visible.
dark.style.opacity=opaque;
dark.style.MozOpacity=opaque;
dark.style.filter='alpha(opacity='+opacity+')';
dark.style.zIndex=zindex;
dark.style.backgroundColor=bgcolor;
dark.style.width= pageWidth;
dark.style.height= pageHeight;
dark.style.display='block';

/* Display the "Loading" box */
var tnode = document.createElement('div'); // Create the layer.
tnode.style.position='absolute'; // Position absolutely
tnode.style.top='0px'; // In the top
tnode.style.left='0px'; // Left corner of the page
tnode.style.overflow='hidden'; // Try to avoid making scroll bars
tnode.style.display='none'; // Start out Hidden
tnode.id='AjaxLoading'; // Name it so we can find it later
tbody.appendChild(tnode); // Add it to the web page
myAjax=document.getElementById('AjaxLoading'); // Get the object.

// Content
// Reset the opacity options. Want this on top
var loadingOptions = loadingOptions || {};
var zindex = loadingOptions.zindex || 100;
var opacity = loadingOptions.opacity || 100;
var opaque = (opacity / 100);
var bgcolor = loadingOptions.bgcolor || '#FFFFFF';

myAjax.style.opacity=opaque;
myAjax.style.MozOpacity=opaque;
myAjax.style.filter='alpha(opacity='+opacity+')';
myAjax.style.zIndex=zindex;

myAjax.style.height= '80px';
myAjax.style.padding = '10px';
myAjax.style.fontSize = '18px';
myAjax.style.width = '200px';
myAjax.style.textAlign = 'center';
myAjax.style.left = '45%';
myAjax.style.top = '25%';
myAjax.style.position = 'absolute';
myAjax.style.border = '2px solid #666';
myAjax.style.backgroundColor = bgcolor;

myAjax.innerHTML='<br>' + loadingOptions.msg + '<br><img src="/i/processing3.gif" id="wait" />';
myAjax.style.display='none';

}
/**
* Adds a function to the window event
* thanks to Adios (http://www.codingforums.com/showthread.php?p=814042)
*/
function addListener(obj, evt, handler)
{
if (obj.addEventListener)
{
obj.addEventListener(evt, handler, false);
}
else if (obj.attachEvent)
{
obj.attachEvent('on' + evt, handler);
}
}
</script>

<script type="text/javascript">
<!--
/*Global JS Variables*/
var htmldb_Img_Dir = "/i/";
//-->
</script>
<link rel="stylesheet" href="/i/css/apex_3_1.css" type="text/css" />
<!--[if IE]><link rel="stylesheet" href="/i/css/apex_ie_3_1.css" type="text/css" /><![endif]-->
<script>
<!--This is added by the page -->
function test(){
alert('Hello');
}
addListener(window, 'beforeunload',test())
</script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script>
addListener(window,'beforeunload',html_Submit_Progress());
</script></head>
<body id="PAGE_BODY">
<a href="#">Click here!></a>
</body>
</html>

Basically, when the user clicks something that would either submit the page or refresh the page I was hoping to run the user defined JS function which in this case is called test(); followed by html_Submit_Progress() which basically greys out the windows and puts up a loading message. html_submit_progress should always fire, its the user define functions which may not always exist which is not a problem as the application simply does not place any code on to the page and therefore is not fired. The error that is being generated in both IE 6 and FF3. In Firebug it recons that tbody is not defined in the function grayOut() line 51 which is this line

tbody.appendChild(tnode); // Add it to the web page

Before I added your code I simply had the body onbeforeunload attribute set to run html_submit_progress and it worked without any errors but would ignore any user defined onbeforeunload events.

Any ideas what maybe causing this error?

adios
05-08-2009, 09:29 PM
I'll have to take a closer look at this later - a lot going on there - but this is definately wrong:

addListener(window, 'beforeunload',test())

... as is this:

addListener(window,'beforeunload',html_Submit_Progress());

You're calling those functions

test()

... instead of simply referencing them

addListener(window, 'beforeunload', test)

... which assigns the function itself, not its return value.

FunkyORACLE
05-08-2009, 09:50 PM
HI adios,

No need to look into it further did those changes and it worked exactly how I was expecting it to work and had no js errors.

Thanks a million,


Just one more thing can I pass values to the function just so that I can inform users to enter only in a function name and not pass the values.


Once again thanks for your help.

adios
05-09-2009, 08:45 PM
Hey Funkmaster ... you're welcome.
Sorry for the delay in responding.

If you want to pass arguments, use an anonymous (http://novemberborn.net/sifr/explained/terminology) function as a wrapper.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>untitled</title>
<script type="text/javascript">

function addListener(obj, evt, handler)
{
if (obj.addEventListener)
{
obj.addEventListener(evt, handler, false);
}
else if (obj.attachEvent)
{
obj.attachEvent('on' + evt, handler);
}
}

function test(str)
{
alert(str);
}

function html_Submit_Progress()
{
document.body.style.background = 'url(http://www.tizag.com/pics/BannerTileBackground.gif) repeat';
}

addListener(window, 'beforeunload', function(){test('Hello')});
addListener(window, 'beforeunload', html_Submit_Progress);

</script>
</head>
<body>
</body>
</html>

Hope that was what you meant. Interesting: note how IE runs the second listener assigned first, while FireFox reverses them. I hate when that happens.

Feel free to post follow-ups. Cheers, Rob

FunkyORACLE
05-13-2009, 11:59 AM
Sorry for not replying,

Its been really hectic here(you know how it goes).

Thanks Rob, I suppose I could also have a wrapper function that could pass the relivant values too.

Example: test(){

test2(somevalue);
test3(some_other_value);
}

and just run test() with your addListener function.

Funny you say that they run in a different order with IE and FF. Is there a way that we could change this saying if broswer is IE then this order else FF another order?

Kor
05-13-2009, 01:33 PM
var isIE=/*@cc_on!@*/false;//IE detector based on IE specific JScript
if(isIE){
//...code for IE ...
}
else{
//... the rest of the browsers...
}