WebDevelopersJournal.comTips on Web Page Design, HTML and Graphics
SITE SEARCH
Newsletters
HTML (M-F) Text (M,TH)



Jobs at webdeveloper.com

Resources By Subject
Technical
Graphical
Authoring
Business
WDJ resources
Archive

internet.com

internet.commerce


Developer Channel


Find a web host with:
CGI Access DB Support Telnet Access
NT Servers UNIX Servers



Semi-automatic?

JavaScript
JavaScript Helper:
Meet Paige Turner, the least geeky geek we've ever come across.

Variables and Operators Explained:
First of a three part guide to JavaScript basics.

Controlling Forms:
Enhance your HTML forms with a touch of JS.

DHTML:
Forget how it works, let's see some in action!


Events And JavaScript: Part 3 - The Event Object

The History Of The World According To JavaScript

by Jon Perry

The Event Object is a very useful addition to the DOM (Document Object Model). The DOM contains many objects that store a variety of information about the browser, the computer running the browser, visited URLs, and so on. The Event Object stores data about events.
March 29, 2000

This is Javascript for IE5. See our policy on browser-specific JavaScript.

During normal program execution, a large number of events occur, so the event object is a fairly active object, constantly changing its properties.

Whenever an event fires, the computer places appropriate data about the event into the event object - for example, where the mouse pointer was on the screen at the time of the event, which mouse buttons were being pressed at the time of the event, and other useful information.

Skilled use of the event object can be very rewarding. It opens up possibilities for creating very intricate and complex programs.

The properties of the event object covered in this article are listed in the following table.

Event Object Property Description
SrcElement The element that fired the event
type Type of event
returnValue Determines whether the event is cancelled
cancelBubble Can cancel an event bubble
clientX Mouse pointer X coordinate relative to window
clientY Mouse pointer Y coordinate relative to window
offsetX Mouse pointer X coordinate relative to element that fired the event
offsetY Mouse pointer Y coordinate relative to element that fired the event
button Any mouse buttons that are pressed
altKey True if the alt key was also pressed
ctrlKey True if the ctrl key was also pressed
shiftKey True if the shift key was also pressed
keyCode Returns UniCode value of key pressed

Once we have received an event, we may need to know more about it, and this is the primary purpose of the event object. As we proceed through this article, you will see how we can successfully employ the event objects to overcome certain types of problems.

The first two properties on the list, srcElement and type, contain the data that effectively encapsulates our object/event pair.

srcElement and type

Of these two event object properties, you will probably find that you use srcElement a lot, and hardly ever use type, but the rare occasions that you do need to use type, it is very useful.

srcElement

The srcElement property returns the element that fired the event. This is an object, and has the same properties as the element.

So, if the we click on an image with an id attribute of 'Image1', and a src attribute of 'picture1.jpg', then event.srcElement.id will return 'Image1', and event.srcElement.src will return 'picture1.jpg', although this will be extended because the computer internally converts relative URLs into absolute URLs.

Similarly, the srcElement has a tagName property:

event.srcElement.tagName will return 'IMG'. And we can also read styles, so if the image has a style height of 100px, then event.srcElement.style.height will return '100px'.

type

The type property contains the other half of an object/event pair, the event name.

If the event we are capturing is the onclick event, the type will be 'click', and if the event is onkeypress, then type will be 'keypress'.

This is the same for non-physical events. If we capture and handle an onload event, type will be 'load', and so on.

To see this in action, we need a fairly complex HTML document.

<HTML>
<HEAD>
<TITLE>srcElement and type</TITLE>
<SCRIPT>
function catchevent() {
eventSrcID=(event.srcElement)?event.srcElement.id:'undefined';
eventtype=event.type;
status=eventSrcID+' has received a '+eventtype+' event.';
}
</SCRIPT>
</HEAD>
<BODY ID="MAINBODY" onload="catchevent();">
<DIV ID="FIRSTDIV" onclick="catchevent();" onmouseover="catchevent();" STYLE="position:absolute;top:10;left:10;height:100;width:200;background-color:red">
</DIV>
<FORM ID="MAINFORM" onmouseout="catchevent();"STYLE="position:absolute;top:150;left:10;height:50;width:200;background-color:yellow">
<INPUT TYPE="TEXT" ID="TEXTBOX" onfocus="catchevent();" onkeypress="catchevent();">
</FORM>
</BODY>
</HTML>

The code consists of a catchevent() function and several HTML elements which call the catchevent() function. Try activating different events over different elements - we get a running commentary on what is happening to our elements.

The catchevent() function reads the event object and determines the source element and the type of the event, then displays this information in the status bar.

We need to include the ternary operator '?' in the code, because some events are not particularly associated with any element. In this case, the onload event is not associated with the <BODY> element as we might expect.

If we use:

eventSrcID=(event.srcElement)?event.srcElement.id:'undefined';

then we are using the ternary operator to provide an alternative in the case of event.srcElement being false. This happens when no element claims to have fired the event.

For those readers who are not completely sure what the ternary operator is, it is shorthand for:

if (event.srcElement) eventSrcID=event.srcElement.id;
Else eventSrcID='undefined';

The technical syntax for '?' is:

variable=(condition)?action if true: action if false;

Once we have the catchevent() function, we add the HTML elements.

Every event that we wish to report on must be captured and sent to the catchevent() function.

This can cause slightly unexpected results - some events may seem mis-placed. This is because of event bubbling, covered in the second article in this series, which allows the event to continue up the element ownership hierarchy.

returnValue and cancelBubble

These two properties are associated with Event Bubbling and Cancelling Events, and were covered in part 2 of this series.

If we set the returnValue property to false, then the event is cancelled.

If we set the cancelBubble property to true, then event bubbling is cancelled.

clientX, clientY, offsetX, offsetY

After we know what caused the event, and what the event is, another set of very useful properties report the position of the mouse pointer when the event happened. These properties contain the mouse co-ordinates when the event was triggered.

(clientX, clientY) returns the position of the mouse pointer on the document, and (offsetX, offsetY) returns the position of the mouse pointer on the element.

The uses for these two co-ordinate systems are subtly different. The best one to select in each circumstance is the one that reduces the number of calculations we must perform.

clientX, clientY

We can use these to tie code in with the any movements of the mouse pointer. A typical example is for enhanced cursors.

An enhanced cursor involves attaching an element to the cursor.

<HTML>
<HEAD>
<TITLE>Enhanced Cursor</TITLE>
</HEAD>
<BODY onmousemove="enhancecursor();" >
<DIV ID="cursorplus" style="position:absolute;top:10;left:10;height:20;width:20;background-color:red"></DIV>
</BODY>
<SCRIPT>
function enhancecursor() {
cursorplus.style.posLeft=event.clientX-10;
cursorplus.style.posTop=event.clientY-10;
}
</SCRIPT>
</HTML>

In this example, the mouse pointer now has a red square attached to it.

Notice that the script element is placed after the body element. This is because the enhancecursor() function uses the element 'cursorplus', which needs to have be defined before the script will understand what 'cursorplus' means.

Once we have defined the 'cursorplus' <DIV> element, we attach it to the cursor by using the enhancecursor() function.

This function changes the left and top coordinates of the <DIV> element to that of the onmousemove event coordinates, and we offset the values slightly to ensure that the enhanced cursor is central.

offsetX, offsetY

These properties return values based on a coordinate system that is internal to the element.

There are several uses for these properties, They can save time and they can provide localised precision for mouse-based code. If we want a co-ordinate for inside an element, we do not particularly want to have to calculate these values from the client system and then subtract the left and top properties. This would prove to be very cumbersome especially if we also wanted to move the element.

Here is an example that demonstrates how these co-ordinates work.

<HTML>
<HEAD>
<TITLE>Offsets</TITLE>
<SCRIPT>
function statusreport() {
status='offsetX : '+event.offsetX+', offsetY : '+event.offsetY;
}
</SCRIPT>
</HEAD>
<BODY>
<DIV onmousemove="statusreport();" style="position:absolute;top:100;left:100;height:200;width:200;background-color:blue"></DIV>
</BODY>
</HTML>

When we move the mouse pointer over the <DIV> element, the local co-ordinates (the position of the mouse pointer relative to the element) are displayed in the status bar.

If we change the function to:

<HTML>
<HEAD>
<TITLE>Offsets</TITLE>
<SCRIPT>
function statusreport() {
status='offsetX : '+event.offsetX+', offsetY : '+event.offsetY+' ; clientX : '+event.clientX+', clientY : '+event.clientY;
}
</SCRIPT>
</HEAD>
<BODY onmousemove="statusreport();">
<DIV style="position:absolute;top:100;left:100;height:200;width:200;background-color:blue"></DIV>
</BODY>
</HTML>

We can see the relationship between the two co-ordinate systems.

Note that in the second example, we have moved the event handler from the <DIV> element to the <BODY> element. This allows us to demonstrate the different element ownership and event firing properties of a document, and we can observe the differences in the co-ordinate systems in more detail.

Next we look at what else was happening when the event was triggered.

button, altKey, ctrlKey, shiftKey

This collection of properties record which mouse buttons were pressed, and if any of the alt key, the ctrl key or the shift key were pressed when the event was triggered.

Once the green box is displayed, try clicking on it with a variety of mouse buttons, and while pressing a selection of the above keys.

<HTML>
<HEAD>
<TITLE>Buttons and Keys</TITLE>
<SCRIPT>
buttonname=new Array('Left','Right','','Middle');
function buttoninfo() {
message='button : '+buttonname[event.button-1]+'\n';
message+='altKey : '+event.altKey +'\n';
message+='ctrlKey : '+event.ctrlKey +'\n';
message+='shiftKey : '+event.shiftKey +'\n';
alert(message);
}
</SCRIPT>
</HEAD>
<BODY>
<DIV onmousedown="buttoninfo();" style="position:absolute;top:100;left:100;height:200;width:200;background-color:#00FF00"></DIV>
</BODY>
</HTML>

The four key components of this program are the four properties.

event.button
event.altKey
event.ctrlKey
event.shiftKey

The button property returns:

Event.button value Description
1 Left Mouse Button
2 Right Mouse Button
4 Middle Mouse Button

The other three key properties return true if the key was pressed, and false otherwise.

As a mask for the button value, we use the buttonname array, which stores the words 'Left', 'Right', and 'Middle' in array positions 0,1 and 3.

The final event object property we shall look at is the keyCode property.

keyCode

The keyCode property holds the UniCode value of any key that is pressed.

The following program demonstrates this. Note that we must use onkeydown if we wish to display non-visible keys, such as Caps Lock or the cursor keys.

<HTML>
<HEAD>
<TITLE>keyCode</TITLE>
</HEAD>
<BODY onkeydown="displaykey();">
<INPUT TYPE="text" name="text1">
</BODY>
<SCRIPT>
function displaykey() {
text1.value=event.keyCode+' : '+String.fromCharCode(event.keyCode);
}
</SCRIPT>
</HTML>

When a key is pressed on the body of the document, the keyCode property is set. This program displays the keyCode value, and the UniCode character from the keyCode value.

Similarly, we can respond to a UniCode value. This program allows you to move the <DIV> element with the cursor keys.

<HTML>
<HEAD>
<TITLE>Cursor Mover</TITLE>
<SCRIPT>
function move() {
ek=event.keyCode;
if (ek==37) DIV1.style.posLeft-=5;
if (ek==39) DIV1.style.posLeft+=5;
if (ek==38) DIV1.style.posTop-=5;
if (ek==40) DIV1.style.posTop+=5;
}
</SCRIPT>
</HEAD>
<BODY onkeydown="move();">
<DIV ID="DIV1" style="position:absolute;top:100;left:100;height:20;width:20;background-color:#FFFF00"></DIV>
</BODY>
</HTML>

This code detects whether the keyCode property corresponds to a cursor key, and then performs an appropriate action.

We can also alter the keyCode property, which is useful to create encryptions.

<HTML>
<HEAD>
<TITLE>Encryption</TITLE>
<SCRIPT>
function encrypt() {
event.keyCode+=1;
}
</SCRIPT>
</HEAD>
<BODY>
<INPUT TYPE="text" name="text1" onkeypress="encrypt();">
</BODY>
</HTML>

And this finishes my discussion on events.

Hope you enjoyed it.



Jon Perry is a Freelance Author and Programmer from the UK.
Suits PonytailsPropheadsContact WDJDiscussWeb AudioSearch



JupiterOnlineMedia

internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

Jupitermedia Corporate Info


Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy.

Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers

Solutions
Whitepapers and eBooks
IBM Whitepaper: Innovative Collaboration to Advance Your Business
Internet.com eBook: Real Life Rails
Avaya Article: Call Control XML - Powerful, Standards-Based Call Control
Internet.com eBook: The Pros and Cons of Outsourcing
Go Parallel Article: Scalable Parallelism with Intel(R) Threading Building Blocks
Internet.com eBook: Best Practices for Developing a Web Site
IBM CXO Whitepaper: The 2008 Global CEO Study "The Enterprise of the Future"
Avaya Article: Call Control XML in Action - A CCXML Auto Attendant
Go Parallel Article: James Reinders on the Intel Parallel Studio Beta Program
IBM CXO Whitepaper: Unlocking the DNA of the Adaptable Workforce--The Global Human Capital Study 2008
Adobe Acrobat Connect Pro: Web Conferencing and eLearning Whitepapers
Go Parallel Article: Getting Started with TBB on Windows
HP eBook: Storage Networking , Part 1
MORE WHITEPAPERS, EBOOKS, AND ARTICLES
Webcasts
Go Parallel Video: Intel(R) Threading Building Blocks: A New Method for Threading in C++
HP Video: Is Your Data Center Ready for a Real World Disaster?
Microsoft Partner Portal Video: Microsoft Gold Certified Partners Build Successful Practices
HP On Demand Webcast: Virtualization in Action
Go Parallel Video: Performance and Threading Tools for Game Developers
Rackspace Hosting Center: Customer Videos
Intel vPro Developer Virtual Bootcamp
HP Disaster-Proof Solutions eSeminar
HP On Demand Webcast: Discover the Benefits of Virtualization
MORE WEBCASTS, PODCASTS, AND VIDEOS
Downloads and eKits
Microsoft Download: Silverlight 2 Software Development Kit Beta 2
30-Day Trial: SPAMfighter Exchange Module
Red Gate Download: SQL Toolbelt
Iron Speed Designer Application Generator
Microsoft Download: Silverlight 2 Beta 2 Runtime
MORE DOWNLOADS, EKITS, AND FREE TRIALS
Tutorials and Demos
IBM IT Innovation Article: Green Servers Provide a Competitive Advantage
Microsoft Article: Expression Web 2 for PHP Developers--Simplify Your PHP Applications
Featured Algorithm: Intel Threading Building Blocks - parallel_reduce
MORE TUTORIALS, DEMOS AND STEP-BY-STEP GUIDES