JavaScript Example 3-2
Handling Events in a Child Window (Events #3)

Click Here for Previous JavaScript Tutorial Home Click Here for Next

I want to launch a child window and establish event handlers for it. How is this done? It's not difficult, but unfortunately, the methods for Netscape4 and IE are different.

Launch the Child Window (using Buttons)

In Example 2-1 we saw how to cause a separate, or "child" window to pop up. Below is a form containing buttons and a text region for launching and writing to a child window. There's nothing really new in this part, except calling JavaScript from button and text elements instead of from links. That actually turned out to be harder to get right than I expected. For one thing, I learned that Netscape buffers the output to the page until it completes a line. Hence the <BR> appended whenever we write text.

   

Here's the HTML for the controls:

<form name="buttons" 
    onSubmit="showMe(document.buttons.writeText.value); return false">
<input NAME="launchButton" TYPE="button" VALUE="Launch Window" 
    onClick="launchChildW()">
<input name="writeStuff" type="button" value="Write Stuff"
    onclick="showMe(document.buttons.writeText.value)">    
<input NAME="writeText" TYPE="text" VALUE="write stuff here..."> 
</form>

And here's the JavaScript code that they invoke.

<script type="text/javascript" language="JavaScript">
 var childW = null;
 function launchChildW() {
   if (childW != null) childW.window.close();
     
   wopts  = 'width=300,height=500,resizable=1,alwaysRaised=1,scrollbars=1';
   childW = window.open('', 'childW', wopts);

   if (childW != null) {
     childW.document.open()
     childW.document.bgColor = "ccffcc";
     childW.document.write('<br>');
     if (childW.opener == null) {
       childW.opener = self;
     }
   } else {
       alert("Failed to open child window");
   }
 }

 function showMe(txt) {
   if (childW == null) {
       // alert("it wasn't open"); return false;
       launchChildW();
     }
   // Note: NN4 won't actually display anything until the line is complete
   // Hence the <BR> is required to flush the text.
   childW.document.writeln(txt + "<BR>");
 }
//-->
</script>

Associating an Event Handler with the Child (Netscape)

This method only works with Netscape Navigator. Press the following button to enable several event handlers for the child window.

Now try clicking in the child window. You should see messages indicating when the "mouseDown", "mouseUp" and "Click" events occur. Here's the HTML code for the button:

    <form name="buttons2">
      <input name="enableButton" type="button" value=
      "Enable Child Click Handler" onclick="enableChild()">
    </form>

For some reason, by holding the mouse button down for more than a second or so, I am able to confuse the event handling system so that it no longer recognizes "Click". No ideas yet on why this occurs...

The JavaScript code for enableChild() is below:

 function handleMe(evnt) {
   // an event object is normally passed to event handlers.
   showMe(evnt.type + " fired... ");
 }

 function enableChild() {
   if (childW == null) launchChildW();
     
   // Here's the Netscape 4 method...
   // Intercept several types of events from the child window.
   childW.captureEvents(Event.CLICK | Event.MOUSEDOWN | Event.MOUSEUP);
     
   // Register handlers for the various events
   childW.onClick = handleMe;
   childW.onMouseDown = handleMe;
   childW.onMouseUp = handleMe;
 }

The comments in the code are pretty self-explanatory. Consult the Netscape documentation for more info.

Associating an Event Handler with the Child (Microsoft IE)

Unfortunately, IE behaves somewhat differently. The first thing you will notice, if you try it, is that IE gags on the JavaScript statement:

   childW.captureEvents(Event.CLICK | Event.MOUSEDOWN | Event.MOUSEUP);

I searched the web at length for a good discussion of the differences, or even for some good documentation on IE's model. While there's an abundance of web-based material on how to use Netscape's events, I was surprised to find much less for IE. What there is mostly discusses the theory of the "bubble-up" event model in a single document (Ryan Detert's IRT tutorial is good at this). The best overall discussion I found is Danny Goodman's article referred to at the top of this page. However even that did not reveal all.

Here is a summary of what needs to change for this code to work in IE:

Putting it All Together

In order to make this all work, we need code to distinguish between Netscape and IE browsers. Here is what Danny Goodman used in his article, it will do fine for present purposes:

var isNav4, isIE4
if (parseInt(navigator.appVersion.charAt(0)) >= 4) {
  isNav4 = (navigator.appName == "Netscape") ? true : false
  isIE4 = (navigator.appName.indexOf("Microsoft" != -1)) ? true : false
}

Using the isNav4 and isIE4 flags along with the code changes described in the preceding section we can now write our event code so that it works with both browsers. Here are the new versions of handleMe and enableChild. The other routines were not modified.

 function handleMe(evnt) {
   // Netscape passes an event object to event handlers,
   // but IE passes nothing.  Note that childW is hard-wired.
   if (isNav4)     showMe(evnt.type + " fired... ")
   else if (isIE4) showMe(childW.event.type + " fired... ")
   else alert("Unknown browser type");
 }

 function enableChild() {
   if (childW == null) launchChildW();
   if (isNav4) {
     // Intercept several types of events from the child window.
     childW.document.captureEvents(Event.CLICK | Event.MOUSEDOWN | Event.MOUSEUP);
    }
   // Register handlers for the various events
   // lowercase event names are NS/IE compatible
   childW.document.onclick = handleMe;
   childW.document.onmousedown = handleMe;
   childW.document.onmouseup = handleMe;
 }

This seems to work fine on both browsers. However, a topic for further investigation is to learn why Netscape sometimes stops handling the click event.

Resources

Netscape JavaScript Developer's Guide
See the section on Events
Netscape JavaScript Reference Manual
Refer to the section on Events
Danny Goodman's article Dueling Event Models: A Cross-Platform Look.
This is a very good article. I wish I had found it sooner.
IRT.org
See Ryan Detert's article Man-Handling Events #1. This is a good article, but it did not reveal the key points needed to get this working on IE. (IRT is where I got the idea for putting the pale green boxes around code examples.)
 
Click Here for Previous JavaScript Tutorial Home Click Here for Next