Ilya Kantor
- Assigning event handlers
- Using a attribute of HTML-tag
- When to use this method
- The element is
this
- Using a DOM-object property
- When to use
- Special methods
- Microsoft solution
- Handlers assignment by W3C standard
- Handlers order
- A cross-browser way of assigning event handlers
- Summary
Most JavaScript-applications perform actions as a response to events.
An event is a signal from the browser that something has happened.
There are many types of events.
- DOM events, which are initiated by DOM-elements. For instance, a
click
event happens when an element is clicked, a mouseover
- when a mouse pointer comes over an element,
- Window events. For instance,
resize
- when a browser window is resized,
- Other events, like
load
, readystatechange
. They are used in AJAX and for other needs.
DOM events connect JavaScript code with the document, providing the means for building dynamical interfaces.
Assigning event handlers
For a script to react on the event, there should be a function assigned to it.
Functions which react on events are called event handlers. They are usually named like "on+event type"
, for instance: onclick
.
JavaScript event handling is single-threaded, so handlers are executed sequentially. That means, if two events happen simultanteously, for example mouseover
(mouse has come over an element) and mousemove
(mouse moved over an element), their handlers will be executed one after another.
There are several ways of assigning an event handler. All of them are given in details below.
Using a attribute of HTML-tag
A handler can be set directly in the markup, right into the attribute named onevent
.
For example, to process a click
event on the input
button, it is possible to assign an onclick
handler like this:
< input id = "b1" value = "Click me" onclick = "alert(‘Thanks!‘);" type = "button" /> |
In action:
The last example uses single quotes inside double quotes. An often newbie mistake is to forget that the code is inside an attribute.
Using them like onclick="alert("Click")"
won’t work. If you really need it, tryonclick="alert("Click")"
. But usually you don’t. Read on for more event handling methods.
It is also possible to call a function for the event handling.
The example below runs a function count_rabbits()
if a button is clicked.
04 |
<script type="text/javascript"> |
05 |
function count_rabbits() { |
06 |
for ( var i=1; i<=3; i++) { |
07 |
alert( "Rabbit " +i+ " out of the hat!" ) |
13 |
< input type = "button" onclick = "count_rabbits()" value = "Count rabbits!" /> |
Please recall that HTML-tag attribute names are case-insensitive, so oNcLiCk
will work same as onClick
oronclick
.
But it is generally considered a good style to use lowercase.
When to use this method
This way of assigning handlers is very convenient - it’s simple and all-inline, that’s why it is sometimes used for really simple tasks.
There are certain drawbacks of this method. When a handler becomes longer than one line - readability suffers greatly.
But, after all, no one writes somewhat complex handlers in HTML. Instead of it, use JavaScript-only ways which are described in the next subsection.
- A simple way for simple tasks
- Mixed JavaScript-code and HTML-markup
- Difficult to write complex handlers
The element is this
Although usage of this event-binding method is not recommended, let’s demonstrate the value of this
with it.
Inside an event handler, this
references the current element. It can be used to get properties on modify the element.
Below, the button
outputs it’s contents using this.innerHTML
:
< button onclick = "alert(this.innerHTML)" >Click me to see me</ button > |
Using a DOM-object property
A closest relative of the way described above - is an assignment using the property named onevent
.
All you need is:
- To get an element
- To assign a handler to the property
onevent
Here is an example of setting a click
handler to the element with id="myElement"
:
1 |
< input id = "myElement" type = "button" value = "Press me" /> |
3 |
document.getElementById( ‘myElement‘ ).onclick = function () { |
In action:
Please, note the two details:
- It is a property, not an attribute. The name of the property is
onevent
, case-sensitive and must belowercased. onClick
won’t work.
- The handler must be a function, not a string.
When the browser meets an on...
attribute in HTML-markup - it basically creates a function from its contents and assigns it to the property.
So these two codes do the same:
- Only HTML:
1 |
< input type = "button" onclick = "alert(‘Click!‘)" value = "Button" /> |
- HTML + JS:
1 |
< input type = "button" id = "button" value = "Button" /> |
3 |
document.getElementById( ‘button‘ ).onclick = function () { |
If there is a handler set in markup, the script overwrites it. In the example below, JavaScript replaces a markup handler with a new one.
1 |
< input type = "button" onclick = "alert(‘Before‘)" value = "Press me" /> |
3 |
document.getElementsByTagName( ‘input‘ )[0].onclick = function () { |
Of course, it is possible to use an existing function:
1 |
function doSomething() { |
5 |
document.getElementById( ‘button‘ ).onclick = doSomething |
An often newbie mistake
Please, note that the function should be assigned, namely doSomething
, notdoSomething()
:
document.getElementById( ‘button‘ ).onclick = doSomething |
doSomething()
- is a result of function execution, and because there is no return
in it, the result will be undefined
.
Compare it against an attribute. Brackets are required there:
< input type = "button" id = "button" onclick = "doSomething()" /> |
The difference is easy to explain. When the browser comes across onclick
attribute, it automatically creates a function from its contents. So the last example is basically same as:
document.getElementById( ‘button‘ ).onclick = function () { |
doSomething() // an autocreated function |
When to use
Assiging handlers using a property is a very simple and popular way.
It has a problem: only one handler for a certain event type can be set.
For example:
input.onclick = function () { alert(1) } |
input.onclick = function () { alert(2) } // replaces the previous handler |
- A convenient and reliable way, works in JavaScript
- A single handler per event
Of course, it’s possible to copy old handler and run it manually inside a new one. But it is better to use more advanced methods of assignment.
Special methods
In a complex JavaScript application, it’s fairly ok that different interface components may be interested in handling the same event.
A classical example is a “document loaded” event and many graphical components which wait for it to initialize themselves.
Microsoft solution
The solution provided by Microsoft and used only in Internet Explorer less than 9
.
It is also supported by Opera for compatibility, but no one uses it there, because Opera also supports another standard-compliant method (see in the next section).
Assigning a handler:
element.attachEvent( "on" +event, handler) |
Removing a handler:
element.detachEvent( "on" +event, handler) |
For instance:
1 |
var input = document.getElementById( ‘button‘ ) |
5 |
input.attachEvent( "onclick" , handler) // assign the handler |
7 |
input.detachEvent( "onclick" , handler) // remove the handler |
An often newbie mistake
Please, note - setting and removal methods need the same handler
object to operate correctly.
This would be wrong:
1 |
input.attachEvent( "onclick" , |
2 |
function () {alert( ‘Thanks‘ )} |
5 |
input.detachEvent( "onclick" , |
6 |
function () {alert( ‘Thanks‘ )} |
In the example below, there are actually two different function objects.
So if it is planned to remove the handler sometime, the reference to it should be stored somewhere.
Using attachEvent
, it is possible to assign multiple handlers to the same event on same element. The example below will work only in IE and Opera:
01 |
< input id = "myElement" type = "button" value = "Press me" /> |
04 |
var myElement = document.getElementById( "myElement" ) |
05 |
var handler = function () { |
09 |
var handler2 = function () { |
10 |
alert( ‘Thanks again!‘ ) |
13 |
myElement.attachEvent( "onclick" , handler) |
14 |
myElement.attachEvent( "onclick" , handler2) |
attachEvent does not pass `this`
The exception is attachEvent
method. Handlers assigned with attachEvent
do not havethis
!
Handlers assignment by W3C standard
W3C or official event handler assignment works in all modern browsers and for IE9.
Assigning a handler:
element.addEventListener( event, handler, phase) |
Removing a handler:
element.removeEventListener( event, handler, phase) |
Please, note that the event name goes without the “on” prefix.
Another difference from the Microsoft syntax is the third parameter - phase, which is usually not used and set to false
.
The usage is generally same as attachEvent
:
1 |
// ... declare a function called handler ... |
2 |
elem.addEventListener( "click" , handler, false ) // assign the handler |
4 |
elem.removeEventListener( "click" , handler, false ) // remove the handler |
So, there is a one big plus and one minus of the special methods:
- As many handlers as you want
- Cross-browser incompatibilities
The incompatibilities is not just different syntax, but there are few other differences. We’ll return to it in the next sections and discuss a cross-browser method of event handling.
Handlers order
Special methods allow to assign multiple handlers to the same event on single object.
Browser does not guarantee the order in which they execute.
Generally, the order of assignment is not related with the order of execution. The order may happen to be same, or inversed or random.
A cross-browser way of assigning event handlers
The task is not so simple as it seems.
There simplest and mostly working solution is to create custom functions which add and remove event handlers using special methods:
01 |
if (document.addEventListener) { |
02 |
var addEvent = function (elem, type, handler) { |
03 |
elem.addEventListener(type, handler, false ) |
05 |
var removeEvent = function (elem, type, handler) { |
06 |
elem.removeEventListener(type, handler, false ) |
09 |
var addEvent = function (elem, type, handler) { |
10 |
elem.attachEvent( "on" + type, handler) |
12 |
var removeEvent = function (elem, type, handler) { |
13 |
elem.detachEvent( "on" + type, handler) |
18 |
addEvent(elem, "click" , function () { alert( ‘hi‘ ) }) |
It works good in most cases, but the handler will lack this
in IE, because attachEvent
doesn’t providethis
.
Fixing this problem may look easy, but it actually isn’t, because of advanced topics like IE<8 memory leaks.
But you don’t need this
and don’t care about memory leaks, then the solution is simple and works well.
Use JavaScript to make the button hide the element with id="hide"
when clicked. Demo:
The source document is here.
Solution
The solution is demonstrated here: tutorial/browser/events/task/hideOther.html.
Create an input button which hides itself when clicked.
Like this:
Open solution
Create a menu which opens/closes on click, like this:
The source and images to start from are at tutorial/browser/events/sliding-src/index.html.
Open hint 1Open solution
There is a message list. Add a delete button to each message to remove it.
The result:
The source is here.
Hint 1
Hint 2
Hint 3
Solution
The solution is shown here.
Summary
There are 3 ways of assigning event handlers: markup, onevent
and special methods.
时间: 2024-11-04 12:49:11