This chapter describes the events that occur when the user interacts with a webpage on iPhone OS. Forms and documents generate the typical events in iPhone OS that you might expect on the desktop. Gestures handled by Safari on iPhone OS emulate mouse events. In addition, you can register for iPhone OS-specific multi-touch and gesture events directly. Orientation events are another example of an iPhone OS-specific event. Also, be aware that there are some unsupported events such as cut, copy, and paste.
Gestures that the user makes—for example, a double tap to zoom and a flick to pan—emulate mouse events. However, the flow of events generated by one-finger and two-finger gestures are conditional depending on whether or not the selected element is clickable or scrollable as described in “One-Finger Events” and “Two-Finger Events.”
A clickable element is a link, form element, image map area, or any other element with mousemove
, mousedown
, mouseup
, or onclick
handlers. A scrollable element is any element with appropriate overflow style, text areas, and scrollable iframe
elements. Because of these differences, you might need to change some of your elements to clickable elements, as described in “Making Elements Clickable,” to get the desired behavior in iPhone OS.
In addition, you can turn off the default Safari on iPhone OS behavior as described in “Preventing Default Behavior” and handle your own multi-touch and gesture events directly. Handling multi-touch and gesture events directly gives developers the ability to implement unique touch-screen interfaces similar to native applications. Read “Handling Multi-Touch Events” and “Handling Gesture Events” to learn more about DOM touch events.
If you want to change the layout of your webpage depending on the orientation of iPhone OS, read “Handling Orientation Events.”
See “Supported Events” for a complete list of events supported in iPhone OS.
It’s very common to combine DOM touch events with CSS visual effects. Read Safari CSS Visual Effects Guide to learn more about CSS visual effects.
This section uses flow charts to break down gestures into the individual actions that might generate events. Some of the events generated on iPhone OS are conditional—the events generated depend on what the user is tapping or touching and whether they are using one or two fingers. Some gestures don’t generate any events on iPhone OS.
One-finger panning doesn’t generate any events until the user stops panning—an onscroll
event is generated when the page stops moving and redraws—as shown in Figure 6-1.
Displaying the information bubble doesn’t generate any events as shown in Figure 6-2. However, if the user touches and holds an image, the image save sheet appears instead of an information bubble.
Finally, a double tap doesn’t generate any events either as shown in Figure 6-3.
Mouse events are delivered in the same order you'd expect in other web browsers illustrated in Figure 6-4. If the user taps a nonclickable element, no events are generated. If the user taps a clickable element, events arrive in this order: mouseover
, mousemove
, mousedown
, mouseup
, and click
. The mouseout
event occurs only if the user taps on another clickable item. Also, if the contents of the page changes on the mousemove
event, no subsequent events in the sequence are sent. This behavior allows the user to tap in the new content.
The pinch open gesture does not generate any mouse events as shown in Figure 6-5.
Figure 6-6 illustrates the mouse events generated by using two fingers to pan a scrollable element. The flow of events is as follows:
If the user holds two fingers down on a scrollable element and moves the fingers, mousewheel
events are generated.
If the element is not scrollable, Safari on iPhone OS pans the webpage. No events are generated while panning.
An onscroll
event is generated when the user stops panning.
Typical events generated by forms and documents include blur
, focus
, load
, unload
, reset
, submit
, change
and abort
. See “Supported Events” for a complete list of supported events on iPhone OS.
Because of the way Safari on iPhone OS creates events to emulate a mouse, some of your elements may not behave as expected on iPhone OS. In particular, some menus that only use mousemove
handlers, as in Listing 6-1, need to be changed because iPhone OS doesn’t recognize them as clickable elements.
Listing 6-1 A menu using a mouseover handler
<span onmouseover = "..." |
onmouseout = "..." |
WHERE TO BUY |
</span> |
To fix this, add a dummy onclick
handler, onclick = "void(0)"
, so that Safari on iPhone OS recognizes the span
element as a clickable element, as shown in Listing 6-2.
Listing 6-2 Adding an onclick handler
<span onmouseover = "..." |
onmouseout = "..." |
onclick = "void(0)"> |
WHERE TO BUY |
</span> |
You can use JavaScript DOM touch event classes available on iPhone OS to handle multi-touch and gesture events in a way similar to the way they are handled in native iPhone OS applications.
If you register for multi-touch events, the system continually sends TouchEvent
objects to those DOM elements as fingers touch and move across a surface. These are sent in addition to the emulated mouse events unless you prevent this default behavior as described in “Preventing Default Behavior.” A touch event provides a snapshot of all touches during a multi-touch sequence, most importantly the touches that are new or have changed for a particular target. The different types of multi-touch events are described in TouchEvent in Safari DOM Additions Reference.
A multi-touch sequence begins when a finger first touches the surface. Other fingers may subsequently touch the surface, and all fingers may move across the surface. The sequence ends when the last of these fingers is lifted from the surface. An application receives touch event objects during each phase of any touch.
Touch events are similar to mouse events except that you can have simultaneous touches on the screen at different locations. A touch event object is used to encapsulate all the touches that are currently on the screen. Each finger is represented by a touch object. The typical properties that you find in a mouse event are in the touch object, not the touch event object.
Note that a sequence of touch events is delivered to the element that received the original touchstart
event regardless of the current location of the touches.
Follow these steps to use multi-touch events in your web application.
Register handlers for multi-touch events in HTML as follows:
<div |
ontouchstart="touchStart(event);" |
ontouchmove="touchMove(event);" |
ontouchend="touchEnd(event);" |
ontouchcancel="touchCancel(event);" |
></div> |
Alternatively, register handlers in JavaScript as follows:
element.addEventListener("touchstart", touchStart, false); |
element.addEventListener("touchmove", touchMove, false); |
element.addEventListener("touchend", touchEnd, false); |
element.addEventListener("touchcancel", touchCancel, false); |
Respond to multi-touch events by implementing handlers in JavaScript.
For example, implement the touchStart
method as follows:
function touchStart(event) { |
// Insert your code here |
} |
Optionally, get all touches on a page using the touches
property as follows:
var allTouches = event.touches; |
Note that you can get all other touches for an event even when the event is triggered by a single touch.
Optionally, get all touches for the target element using the targetTouches
property:
var targetTouches = event.targetTouches; |
Optionally, get all changed touches for this event using the changedTouches
property:
var changedTouches = event.changedTouches; |
Access the Touch
object properties—such as the target, identifier, and location in page, client, or screen coordinates—similar to mouse event properties.
For example, get the number of touches:
event.touches.length |
Get a specific touch object at index i
:
var touch = event.touches[i]; |
Finally, get the location in page coordinates for a single-finger event:
var x = event.touches[0].pageX; |
var y = event.touches[0].pageY; |
You can also combine multi-touch events with CSS visual effects to enable dragging or some other user action. To enable dragging, implement the touchmove
event handler to translate the target:
function touchMove(event) { |
event.preventDefault(); |
curX = event.targetTouches[0].pageX - startX; |
curY = event.targetTouches[0].pageY - startY; |
event.targetTouches[0].target.style.webkitTransform = |
'translate(' + curX + 'px, ' + curY + 'px)'; |
} |
Typically, you implement multi-touch event handlers to track one or two touches. But you can also use muti-touch event handlers to identify custom gestures. That is, custom gestures that are not already identified for you by gesture events described in “Handling Gesture Events.” For example, you can identify a two-finger tap gesture as follows:
Begin gesture if you receive a touchstart
event containing two target touches.
End gesture if you receive a touchend
event with no preceding touchmove
events.
Similarly, you can identify a swipe gesture as follows:
Begin gesture if you receive a touchstart
event containing one target touch.
Abort gesture if, at any time, you receive an event with >1 touches.
Continue gesture if you receive a touchmove
event mostly in the x-direction.
Abort gesture if you receive a touchmove
event mostly the y-direction.
End gesture if you receive a touchend
event.
Multi-touch events can be combined together to form high-level gesture events.
GestureEvent
objects are also sent during a multi-touch sequence. Gesture events contain scaling and rotation information allowing gestures to be combined, if supported by the platform. If not supported, one gesture ends before another starts. Listen for GestureEvent
objects if you want to respond to gestures only, not process the low-level TouchEvent
objects. The different types of gesture events are described in GestureEvent in Safari DOM Additions Reference.
Follow these steps to use gesture events in your web application.
Register handlers for gesture events in HTML:
<div |
ongesturestart="gestureStart(event);" |
ongesturechange="gestureChange(event);" |
ongestureend="gestureEnd(event);" |
></div> |
Alternatively, register handlers in JavaScript:
element.addEventListener("gesturestart", gestureStart, false); |
element.addEventListener("gesturechange", gestureChange, false); |
element.addEventListener("gestureend", gestureEnd, false); |
Respond to gesture events by implementing handlers in JavaScript.
For example, implement the gestureChange
method as follows:
function gestureChange(event) { |
// Insert your code here |
} |
Get the amount of rotation since the gesture started:
var angle = event.rotation; |
The angle is in degrees, where clockwise is positive and counterclockwise is negative.
Get the amount scaled since the gesture started:
var scale = event.scale; |
The scale is smaller if less than 1.0
and larger if greater than 1.0
.
You can combine gesture events with CSS visual effects to enable scaling, rotating, or some other custom user action. For example, implement the gesturechange
event handler to scale and rotate the target as follows:
onGestureChange: function(e) { |
e.preventDefault(); |
e.target.style.webkitTransform = |
'scale(' + e.scale + startScale + ') rotate(' + e.rotation + startRotation + 'deg)'; |
} |
iPhone OS Note: The preventDefault
method applies to multi-touch and gesture input in iPhone OS 2.0 and later.
The default behavior of Safari on iPhone OS can interfere with your application’s custom multi-touch and gesture input. You can disable the default browser behavior by sending the preventDefault
message to the event object.
For example, to prevent scrolling on an element in iPhone OS 2.0, implement the touchmove
and touchstart
event handlers as follows :
function touchMove(event) { |
// Prevent scrolling on this element |
event.preventDefault(); |
... |
} |
To disable pinch open and pinch close gestures in iPhone OS 2.0, implement the gesturestart
and gesturechange
event handlers as follows:
function gestureChange(event) { |
// Disable browser zoom |
event.preventDefault(); |
... |
} |
An event is sent when the user changes the orientation of iPhone OS. By handling this event in your web content, you can determine the current orientation of the device and make layout changes accordingly. For example, display a simple textual list in portrait orientation and add a column of icons in landscape orientation.
Similar to a resize
event, a handler can be added to the <body>
element in HTML as follows:
<body onorientationchange="updateOrientation();"> |
where updateOrientation
is a handler that you implement in JavaScript.
In addition, the window
object has an orientation
property set to either 0
, -90
, 90
, or 180
. For example, if the user starts with the iPhone in portrait orientation and then changes to landscape orientation by turning the iPhone to the right, the window’s orientation
property is set to -90
. If the user instead changes to landscape by turning the iPhone to the left, the window’s orientation
property is set to 90
.
Listing 6-3 adds an orientation handler to the body element and implements the updateOrientation
JavaScript method to display the current orientation on the screen. Specifically, when an orientationchange
event occurs, the updateOrientation
method is invoked, which changes the string displayed by the division element in the body.
Listing 6-3 Displaying the orientation
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" |
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
<html xmlns="http://www.w3.org/1999/xhtml"> |
<head> |
<title>Orientation</title> |
<meta name = "viewport" content="width=320, user-scalable=0"/> |
<script type="text/javascript" language="javascript"> |
function updateOrientation() |
{ |
var displayStr = "Orientation : "; |
switch(window.orientation) |
{ |
case 0: |
displayStr += "Portrait"; |
break; |
case -90: |
displayStr += "Landscape (right, screen turned clockwise)"; |
break; |
case 90: |
displayStr += "Landscape (left, screen turned counterclockwise)"; |
break; |
case 180: |
displayStr += "Portrait (upside-down portrait)"; |
break; |
} |
document.getElementById("output").innerHTML = displayStr; |
} |
</script> |
</head> |
<body onorientationchange="updateOrientation();"> |
<div id="output"></div> |
</body> |
</html> |
Be aware of all the events that iPhone OS supports and under what conditions they are generated. Table 6-1 specifies which events are generated by Safari on iPhone OS and which are generated conditionally depending on the type of element selected. This table also lists unsupported events.
iPhone OS Note: Although drag and drop are not supported, you can produce the same effect using touch events as described in “Using Touch to Drag Elements” in Safari CSS Visual Effects Guide.
Event | Generated | Conditional | Available |
---|---|---|---|
| Yes | Yes | iPhone OS 1.0 and later. |
| Yes | Yes | iPhone OS 1.0 and later. |
| Yes | Yes | iPhone OS 1.0 and later. |
| Yes | Yes | iPhone OS 1.0 and later. |
| Yes | Yes | iPhone OS 1.0 and later. |
| Yes | Yes | iPhone OS 1.0 and later. |
| Yes | No | iPhone OS 1.0 and later. |
| Yes | No | iPhone OS 1.0 and later. |
| Yes | No | iPhone OS 1.0 and later. |
| Yes | No | iPhone OS 1.0 and later. |
| Yes | No | iPhone OS 1.0 and later. |
| Yes | No | iPhone OS 1.0 and later. |
| Yes | No | iPhone OS 1.0 and later. |
| Yes | No | iPhone OS 1.0 and later. |
| No | N/A | |
| No | N/A | |
| No | N/A | |
| No | N/A | |
| No | N/A | |
| No | N/A | |
| Yes | N/A | iPhone OS 1.1.1 and later. |
| Yes | N/A | iPhone OS 2.0 and later. |
| Yes | N/A | iPhone OS 2.0 and later. |
| Yes | N/A | iPhone OS 2.0 and later. |
| Yes | N/A | iPhone OS 2.0 and later. |
| Yes | N/A | iPhone OS 2.0 and later. |
| Yes | N/A | iPhone OS 2.0 and later. |
| Yes | N/A | iPhone OS 2.0 and later. |
Last updated: 2010-03-24