Document directory
- Table 1. popular event object attributes
Three event models are supported at the same time.
The event gives the client JavaScript a chance to be activated and run. After a Web page is loaded, the only way to run the script is to respond to system or user actions. Although simple events have been implemented as part of JavaScript since the advent of the first browser that supports scripting, most recently appeared browsers have implemented strong event models, allows scripts to process events more intelligently. The problem is: to support various browsers, you must fight against multiple advanced event models. To be precise, there are three.
The three event models are aligned with the following Document Object Model (DOM): Netscape Navigator 4 (nn4 ), internet Explorer 4 and its latest version (ie4 +) for Macintosh and Windows systems, and W3C Dom implemented in safari. Although there are some essential differences between these models, they can be applied to the same document with the help of some simple JavaScript. This article focuses on two key aspects of the conflicting event model:
- Binds an event to an HTML element.
- How to handle an event after it is triggered.
Event binding method
Event binding refers to the process of constructing an HTML element in response to a system or user action. There are no less than five event binding technologies in different browser versions. The following describes these technologies quickly.
Event binding method I: bind element attributes
The simplest and best way to bind events to attributes of element identifiers is to bind events. The event property name consists of the event type and the prefix "on. Although HTML attributes are not case sensitive, people define a rule that specifies that the first letter of each "word" of the event type is capitalized, such as onclick and onmouseover. These attributes are also called Event Handlers because they indicate how elements "process" specific event types.
The correct value of the event processor attribute is a javascript statement enclosed in quotation marks. The most common value is a statement that calls a script function, And the called function is defined in the <SCRIPT> identifier at the front of the document-This identifier is usually located in the
function myFunc() {// script statements here}
It can be defined as an event processor of a key control. The key definition is as follows:
<INPUT TYPE="button" NAME="myButton" VALUE="Click Here"onClick="myFunc()">
Binding events to element attributes has the advantage that developers can pass parameters to the event processor functions. The reference of the element that receives the event is passed by a special parameter value -- this keyword. The following code demonstrates how a function converts the content of any number of text boxes into uppercase using input parameters:
<SCRIPT LANGUAGE="JavaScript">function convertToUpper(textbox) {textbox.value = textbox.value.toUpperCase();}</SCRIPT>...<FORM ....><INPUT TYPE="text" NAME="first_name" onChange="convertToUpper(this)"><INPUT TYPE="text" NAME="last_name" onChange="convertToUpper(this)">...</FORM>
Event binding method II: bind Object Attributes
For the nn3 + and ie4 + browsers, the script programmer can bind the event to the object in the form of a script statement, instead of binding the event to the attribute of the element identifier. Each element object responsible for Event Response sets corresponding attributes for events that can be identified by the user. The object property name is in the lower case of the element identity property, such as onmouseover. Nn4 also accepts the attribute name of intercap (that is, the first letter and the next word are capitalized) versions. However, considering cross-browser compatibility, it is safer for all letters to be lowercase.
When you assign a function reference to an event attribute, a binding occurs. Function reference refers to the function name, but does not contain brackets in the function definition. Therefore, if you want to bind a click event named mybutton to activate a function defined as myfunc (), the assignment statement is as follows:
document.forms[0].myButton.onclick = myFunc;
Note: When an event is triggered, there is no way to pass parameters to the event function. This article will review this issue later in the discussion of the event processing process.
Event binding method III: Binding ie4 + <script for> ID
In ie4 +, Microsoft extends the <SCRIPT> identifier to bind the script statements contained in the identifier to an event type of an element. The identity attribute that supports this binding (which has not been approved by W3C as part of HTML) is for and event.
The value of the for Attribute must be the unique identifier you have assigned to the element's ID attribute. Then, you must assign the event name (onmouseover, onclick, and so on) to the event attribute. On the basis of the preceding key instance, we must modify the key ID to include an ID attribute:
<INPUT TYPE="button" NAME="myButton" ID="button1" VALUE="Click Here">
The script statement is not in the function, but in the <SCRIPT> identifier, as shown below:
<SCRIPT FOR="button1" EVENT="onclick">// script statements here</SCRIPT>
Of course, the statement in the identifier can call any function defined elsewhere on the page (or the function imported from the. js file ). However, this binding method means that you must create a <script for> identifier for each element and each event.
You must be careful that you can only deploy this binding method on a page that is only available for ie4 + browsers. Any browser that supports Script Programming but does not implement this special <SCRIPT> identifier (including ie3) will treat it as a regular <SCRIPT> identifier, and tries to execute these script statements when loading the page -- this inevitably causes a script error.
Event binding method IV: Use the attachevent () method of ie5/Windows
As early as the W3C Dom Working Group honed the standard event model, the attachevent () method has been implemented and can be used for every HTML element in ie5 for Windows or an updated version of browsers.
The attachevent () method is used as follows:
elemObject.attachEvent("eventName", functionReference);
The value of the eventname parameter is a string that represents the event name, such as onmousedown. The functionreference parameter is a function reference without parentheses, which is the same as the event attribute method described earlier. Therefore, for the key object in the preceding example, you can bind the function to the Click Event of the key using the following script statement:
document.getElementById("button1").attachEvent("onclick", myFunc);
Because the attachevent () method must strictly work in the ie5 +/Windows environment, you can use the W3C Dom element reference method (as shown above ), you can also use the reference method of ie4 +:
document.all.button1.attachEvent("onclick", myFunc);
This method is worth noting that you cannot execute this statement before the element is loaded into the browser. The reference of this object is invalid until the HTML key element is created by the browser. Therefore, you need to run such binding statement at the bottom of the page or in the function called by the onload event processor of the Body element.
Event binding method V: Use the addeventlistener () method of W3C dom
Safari uses the event binding mechanism defined by W3C Dom Level 2. This mechanism is similar to the attachevent () method of ie5/windows, but has its own syntax. The W3C DOM specification defines an addeventlistener () method for each node in the DOM hierarchy. HTML elements are a class of DOM nodes. A text node inside a pair of element identifiers is also a node and can receive events. This is often reflected in the handling of nn6 events. You will see it later in this article.
The syntax of the addeventlistener () method is as follows:
nodeReference.addEventListener("eventType", listenerReference, captureFlag);
In the W3C Dom standard, the addeventlistener () method registers an event for the specified node, indicating that the node wants to process the event. The first parameter of this method is a string that declares the event type (without the "on" prefix), such as click, mousedown, and keypress. The second parameter of the addeventlistener () method can be treated the same as the function reference described earlier. The third parameter is a Boolean value indicating whether the node listens for events in the so-called capture mode in the Dom. Capture and dispatch of events-in combination, they are called event propagation-which is finally described in another article. For a typical event listener, the third parameter should be false ).
Which binding method is best?
If you are lucky enough to create an application for a browser of a specific version on an operating system, you can select the most modern binding mode for the selected browser. However, for cross-browser website authors, selection of binding methods requires substantial challenges.
If you only plan to support ie5/Mac, you can ignore the attachevent () and addeventlistener () methods, because ie5/MAC does not support both methods. In this case, there are two actual options: bind the identity attribute or bind the object attribute. In this case, you have to worry about it.
On the one hand, W3C Dom Level 2 recognizes the identity-based method and recommends it as an acceptable alternative to the addeventlistener () method. To be compatible with millions of scripts, all browsers that support Script Programming support the event binding method based on the identity attribute. Some automated page creation tools, such as Dreamweaver, also embed the attributes of the event processor into the HTML identifier.
On the other hand, embedding script-oriented information in the element identification file cannot separate the content from the style and behavior, which is contrary to the current popular trend. The method for binding an event to an object property sounds correct, but in W3C standards on HTML, XHTML, or DOM, there is no "official" Support for event attributes. In reality, this method is supported by other browsers except the first generation that supports Script Programming.
A purely standard author will think that both of the above methods have disadvantages, but for actual developers, even considering the compatibility of mainstream browsers in the future, both methods are "secure.
Event information mining: event object
The core of all three event models is an event object-an abstract entity. Its Attributes contain a lot of information that has potential value for event processing functions. From the discussion of the event binding technology earlier in this article, you may infer that the event object is critical to the script, one of the reasons is that in addition to the identity attribute-based binding method, other binding methods do not support passing parameters to the event handler.
The event object fills this gap by providing enough "hooks" so that the event processing function can read the features of the event. Therefore, the event processing function can get reference to the elements that receive the event and some other useful information, such as the coordinates of the mouse action, the buttons used by the mouse, and the keys pressed on the keyboard, and whether the modifier key is pressed during the event (for example, the shift-click event is detected ).
Access event object
Although the precise composition of event objects varies with the three types of dom (nn4, ie4 +, and W3C/Safari) discussed in this article, an event processing function can only access event objects in one of the following two ways: NN and IE. The W3C/Safari DOM Event object is published to the script in the same way as the event object of nn4, while ie4 + has its own method.
The ie4 + event object is easier to describe, so we will discuss it first. Simply put, the event object is an attribute of the window object. This means that only one event object exists in all instances. For example, simply pressing and releasing a button on the keyboard produces three events: onkeydown, onkeypress, and onkeyup (the event occurrence sequence is the same as the list order here ). If the onkeydown event activation function takes a long time to process, the browser will keep the other two events in the queue until the onmousedown event processing is complete.
For nn4 and W3C Dom, the event object looks more abstract. In addition to the binding method based on the identity property style, other binding methods are to automatically pass the event object to the function bound to the event. A single parameter is passed to the function. The developer needs to define a parameter variable in the function to "receive" the value of this parameter. To avoid conflict with the window. event object in IE, do not name the parameter event. For example, it is quite good to name it EVT. The corresponding event functions are defined as follows:
function myFunc(evt) {// script statements here}
However, if you are using the event binding technology based on the identity attribute, you must explicitly pass the event as a parameter to the function you call. To complete event transfer, the keyword event must be passed as a parameter:
onClick = "myFunc(event)"
External parameters are the only link between your event handler function and the event object of NN. If other functions called within the main event processing function need the object or the attribute value of the object, you can relay the object or its attribute value to these functions as parameters.
If you want to know whether ie saves the event reference in the window. Event attribute, the answer is "yes ". Using this syntax intersection is quite secure, because in the NN and IE browsers, the event objects passed to the event processing function have the attribute values of the current event you expect.
Compatible with two event object references
Imagine that when processing an event, we need to examine one or more event attributes in an event function. This is a simple technique that allows event processing functions to work together with the event objects passed in as parameters, or read information from the window. Event attribute. Moreover, this technology does not have to deal with the nuances between different browser versions.
At the beginning, you need to define a parameter variable in your event handler function to prepare to receive the event objects that may be passed in. Then, the browser event object is assigned to the preceding parameter variables through a simple conditional expression:
function myFunc(evt) {evt = (evt) ? evt : ((window.event) ? window.event : "")// process event here}
If the event object is passed in as a parameter, the event object is stored in the EVT local variable within the function. If this parameter is null and the browser's window object contains an event attribute, the window. event object will assign itself to the EVT variable.
However, in order to do this, one or more layers of conditional control should be included to elegantly adapt to early browsers that do not define event objects in the event model:
function myFunc(evt) {evt = (evt) ? evt : ((window.event) ? window.event : "")if (evt) {// process event here}}
To apply the same method to the construction of all event processing functions, you can define a function to be compatible with two types of events, that is, the event object explicitly passed in by the bound identity attribute, and the event objects implicitly passed in by Bound event properties. In this way, even if you change the event Binding style during development, this function does not need to be changed.
Swedish buffet selection of event objects
However, creating a reference pointing to an event object is only part of the battle. Each event object from different event models has its own set of attributes to accommodate event details. The following table lists the most common attributes and the names of these attributes in the preceding three event object types.
Table 1. popular event object attributes
Description |
Nn4 |
Ie4 + |
W3C/Safari |
Event Target |
Target |
Srcelement |
Target |
Event Type |
Type |
Type |
Type |
X coordinate on page |
Pagex |
* |
Pagex |
Y coordinate on page |
Pagey |
* |
Pagey |
Mouse button |
Which |
Button |
Button |
Keyboard key |
Which |
Keycode |
Keycode |
The attribute value of the annotation * can be obtained by evaluating event. clientx + document. Body. scrolltop or event. clienty + document. Body. scrolltop.
Ie5 of the Macintosh version generally follows the ie4 + event object model, but with an exception, the ie5/MAC event object defines both the srcelement attribute, the target attribute is also defined. Both attributes point to the element that receives the event.
The attribute of the most important event object to be abstracted may be a reference to the HTML element that receives the event. The event objects of nn4 and W3C use the same attribute name (target), while the event objects of ie4 + use the srcelement attribute. At this time, the object detection technology (rather than the laborious and dangerous browser version recognition method) has once again saved us. For non-text container elements, a simple conditional expression can easily handle the differences in script Syntax:
var elem = (evt.target) ? evt.target : evt.srcElement
From now on, your script can read and write the Element Object Attributes published by any browser object model.
W3C Dom node event Target
The W3C Dom node architecture allows every node in the document to receive events. In browsers that support this architecture, events that occur on the top of the nested text do not call the event processor assigned to the text container. The corresponding text node is the target node of the event. Consider the following scenarios:
In an event instance, when the pointer of the mouse scrolls over the text contained in a span element, the text is highlighted. The event binding process is carried out through the object attributes in the init () function. On the surface, When you scroll the mouse over a span element, the onmouseover event Action Function assigns a class name (highlight) associated with the style form rule to the element ), this style rule defines the text display style as bold and yellow background. In the onmouseout function, the style is restored to the original version (class normal ). Note how a togglehighlight () function executes two actions with the help of the type attribute of the event object (the attribute has the same name among all event model objects ). Please try this event instance.
However, if you load the example to nn6, the real target of the mouse event is the text node in the span element. This article does not discuss the event propagation mechanism, but please believe that, the default behavior of the W3C DOM event model will cause events to spread up the hierarchy of nodes (similar to the Mechanism in ie4 + for events to spread up through element containers ). Therefore, in this event instance. The mouse event is passed to the container (that is, the span element) of the text node from its real target ). These events trigger the corresponding event processor in the span element.
Although the event processor belongs to the span element, the event object retains the reference of the Text object and uses it as the original object of the event. However, the style of a text node can be modified only when the container acts on the text node. To implement the equivalent operation of the togglehighlight () function, so that the classname attribute of the span container can be modified, the function needs to derive a reference pointing to the text node container.
One policy is to use the currenttarget attribute of the W3C DOM Event object, which returns a reference of the node that handles the event. The decision tree in the script needs to consider this attribute. The togglehighlight () function after the code is added is as follows:
function toggleHighlight(evt) {evt = (evt) ? evt : ((window.event) ? window.event : "")if (evt) {var elemif (evt.target) {if (evt.currentTarget && (evt.currentTarget != evt.target)) {elem = evt.currentTarget} else {elem = evt.target}} else {elem = evt.srcElement}elem.className = (evt.type == "mouseover") ? "highlight" : "normal"}}
Another optional method is to check the includetype attribute of the object returned by the target attribute. A browser that can direct events to text nodes can also report the nodetype attribute value of a text node to 3 rather than the type of the element node (the value is 1 ). If the event target is a text node, the script program can reference the parent element node through the parentnode attribute of the text node. To some extent, the decision tree of this method has been improved:
function toggleHighlight(evt) {evt = (evt) ? evt : ((window.event) ? window.event : "")if (evt) {var elemif (evt.target) {elem = (evt.target.nodeType == 3) ? evt.target.parentNode : evt.target} else {elem = evt.srcElement}elem.className = (evt.type == "mouseover") ? "highlight" : "normal"}}
If you are reading this article using a browser that follows W3, try the modified version to see the style changes when you scroll the mouse.
This page uses the togglehighlight () function embedded in the latest version of the event instance to demonstrate how to use JavaScript to add additional value to browsers that can display the expected results, at the same time, the basic content can also be provided to users who still use older versions or do not support Script Programming, but the mode is not so dynamic and easy to interact.
Template of an event processing function
Not every event handler function processes the same attributes or actions in the page Element Object. However, a template can be derived from the above discussion, you can start encoding with the help of this template. The template is as follows:
function functionName(evt) {evt = (evt) ? evt : ((window.event) ? window.event : "")if (evt) {var elemif (evt.target) {elem = (evt.target.nodeType == 3) ? evt.target.parentNode : evt.target} else {elem = evt.srcElement}if (elem) {// process event here}}}
Replace the function name in the first line with the expected function name, and start to write the code for the specific event where you are watching the instruction. This format should provide you with a starting point, suitable for any cross-browser event Binding style you adopt. If you need to use this format multiple times on a page, you can further streamline the code by abstracting the code that reads the target into a reusable tool function, then, call each event processing function:
// shared functionfunction getTargetElement(evt) {var elemif (evt.target) {elem = (evt.target.nodeType == 3) ? evt.target.parentNode : evt.target} else {elem = evt.srcElement}return elem}function functionName(evt) {evt = (evt) ? evt : ((window.event) ? window.event : "")if (evt) {var elem = getTargetElement(evt)if (elem) {// process event here}}}
With such a framework, you should be able to focus more on the specific actions required by the processing functions of each event.