Pointer and gesture events in Internet Explorer 10

Note  For more current overviews on these topics, see the Pointer Events and Gesture Events topics.

 

Caution  The W3C Pointer Events specification has undergone several revisions since its implementation in Internet Explorer 10. Additionally, the MS vendor prefixes on Pointer Events APIs are deprecated as of Internet Explorer 11. See Pointer Events updates for a summary of changes and compatibility best practices.

 

Internet Explorer 10 and Windows apps using JavaScript for Windows 8 introduce support in the web platform for handling touch and pen input. Rather than requiring you to create code that handles each type of input separately, Internet Explorer 10 introduces the concept of a pointer.

A pointer is any point of contact on the screen: it can be a mouse, finger, or pen. You can now easily provide a consistent experience across input hardware and form factors by writing to a single set of pointer events that encapsulate input from mouse, touch, and pen.

Pointer events

Similar to mouse events, pointer events fire on down, move, up, over, and out for each pointer:

In contrast to a mouse, it's possible to have multiple pointers on the screen at one time (using, for example, multi-touch hardware). In these scenarios, a separate pointer event fires for each point of contact, making it easy to build multi-touch-enabled sites and applications.

Pointer cancellation

When using touch or pen input, sometimes pointers on the screen can be canceled. For example, if your screen supports no more than two simultaneous touch points and you add a third finger to the screen, one of the other points will be canceled because the hardware cannot track three points. Pointer cancellation is indicated by the MSPointerCancel event.

Mouse compatibility

After firing pointer events, Internet Explorer 10 fires mouse events for the primary contact (for example, the first finger on the screen). This enables existing websites that are based on mouse events to continue to function.

Feature detection

Here's the best way to detect support for pointer events:

if (window.navigator.msPointerEnabled) {
  // Pointer events are supported.
}

Be aware that this feature detection is not an indication that the device supports touch or pen input. Rather, it indicates the platform will fire pointer events for whatever hardware is present in the system.

The following example is a basic finger paint app that works with mouse, touch, and pen via pointer events.

<!DOCTYPE html>
<html>
<head>
  <title>Scribble touch example</title>
<style>
  html { 
    -ms-touch-action: none; /* Direct all pointer events to JavaScript code. */
  }
</style>

<script>
  window.addEventListener('load', function () {
    var canvas = document.getElementById("drawSurface"),
    context = canvas.getContext("2d");
    if (window.navigator.msPointerEnabled) {
      canvas.addEventListener("MSPointerMove", paint, false);
    }
    else {
      canvas.addEventListener("mousemove", paint, false);
    }
    function paint(event) {
      // paint a small rectangle every time the event fires. 
      context.fillRect(event.clientX, event.clientY, 5, 5);
    }
  });
</script>

</head>
<body>

  <canvas id="drawSurface" width="500px" height="500px" style="border:1px solid black;">Canvas isn't supported by this browser or document mode</canvas>
</body>
</html>

Common practices for touch optimization

Internet Explorer 10 provides common default handling for basic touch interactions, for example:

  • Panning for scrollable regions
  • Pinch zooming
  • Press-and-hold context menus
  • Touch selection

These features work automatically so that sites and apps have a great touch experience by default. However, you might want to disable them in favor of your own experience.

Testing for touch support

Testing for touch capability, and whether multi-touch is supported is easy using the msMaxTouchPoints property. To check if a device can support touch, and if so, how many points, use the following:

// To test for touch capable hardware 
if(navigator.msMaxTouchPoints) { ... }

// To test for multi-touch capable hardware
if(navigator.msMaxTouchPoints && navigator.msMaxTouchPoints > 1) { ... }

// To get the maximum number of points the hardware supports
var touchPoints = navigator.msMaxTouchPoints;

Panning and zooming

Pointer events won't fire while performing a pan or zoom. In scenarios like the previous paint application example, disable panning and zooming on a region so that you can consume these events for your own purpose. This is done by using Cascading Style Sheets (CSS), for example.

.disablePanZoom {
  -ms-touch-action: none; /* Disables all pan/zoom behaviors and fire pointer events in JavaScript instead. */
}

Touch selection

You can select a word using touch in Internet Explorer 10 by tapping on or near text. If you want to disable text selection, do it just like you did in Windows Internet Explorer 9.

element.addEventListener("selectstart", function(e) { e.preventDefault(); }, false);
 // Disables selection

Context menus

Pressing and holding certain elements in Windows Internet Explorer shows a hold visual that indicates a context menu is about to appear. If you raise your finger, the context menu is shown. If you drag your finger away, the visual is dismissed and the context menu does not appear.

If you want to use your own context menu, you can still do that with Internet Explorer 10. Just call event.preventDefault on the contextmenu event and run code to display your context menu. Internet Explorer automatically makes your context menu work with touch and provides the same hint visual upon press and hold. This example uses a contextmenu event to detect when the user has pressed on an element, held, and released. When the user lifts their finger, the contextmenu event fires, and a message is displayed.

<!DOCTYPE html>
<html >
<head>
     <title>Touch and hold example</title>
  <style>
   
    #touchspot {
      width:100px;
      height:100px;
      background-color:aquamarine;
      border:solid 2px black;
    }
  </style>

</head>
<body>
  <div id="touchspot">Touch and hold me</div>

  <script>
    var elm = document.getElementById("touchspot");

    elm.addEventListener("contextmenu", function (e) {
      e.target.innerHTML = "Touch has pressed, held, and lifted, or mouse has been right clicked. Time to show a custom menu.";
      e.preventDefault();    // Disables system menu
    }, false);

  </script>
</body>
</html>

If you don't want a context menu at all, such as for a game that requires the user to hold a finger down for awhile, you might want to disable both the default context menu and the hint visual. To do this, you just need to cancel two events.

 // Disables visual
element.addEventListener("MSHoldVisual", function(e) { e.preventDefault(); }, false);
// Disables menu
element.addEventListener("contextmenu", function(e) { e.preventDefault(); }, false);
 

Gesture object and events

In addition to pointer events, Windows 8 has the ability to recognize complex interactions called gestures (such as pinch, swipe, and so on) in a consistent way across applications.

Note  The APIs described in this section are not supported in Windows 7.

 

The MSGesture object used in the previous example enables higher level gestures such as hold, pan, and tap easily without capturing every pointer event yourself. The catch is that you need to capture the onmspointerdown event, and configure the MSGesture object with the target (the object you want gesture events from), and the pointerId. Without instantiating an MSGesture object and configuring it, your element will only fire pointer events.

Gesture events incorporate additional information than straight pointer events. For example, when a user touches and removes their finger immediately, it fires an MSGestureTap event. If the user touches the surface and keeps their finger there, it fires an MSGestureHold event.

When the user swipes their finger, MSGestureStart, MSGestureChange, and MSGestureEnd events are fired.

If the user swipes quickly and raises their finger, anMSInertiaStart event is fired.

Note  You can detect when a gesture is in its inertia phase when the event detail property for the MSGestureChange event is equal to event.MSGESTURE_FLAG_INERTIA.

 

Inertia is movement that continues after you remove the contact with the screen. Inertia support is built in to gesture objects in Internet Explorer 10, and doesn't require any additional code other than handlers for the events. The MSInertiaStart event is followed by a series of MSGestureChange events, depending on the speed of the swipe, before an MSGestureEnd event is fired. The MSInertiaStart event fires only when there is enough speed to a swipe and can help your code differentiate between a slow move and a quick flick.

Here are the primary gesture events:

The MSGestureEvent object that's passed to every event returns properties that help your app determine the state of the object being manipulated. To see if the user has tried to zoom or resize the element, use the scale property. If the user rotates the element on the screen, you can get the angle in radians with the rotation property. Both of these properties are changes that have been made since the last MSGestureEvent happened.

Gesture flags

The MSGesture flags return the status of an event object, such as MSGestureStart, MSGestureChange, or MSGestureHold. They are:

  • MSGESTURE_FLAG_NONE , no special status.
  • MSGESTURE_FLAG_BEGIN, flags the beginning of a gesture event.
  • MSGESTURE_FLAG_END, flags the end of a gesture event.
  • MSGESTURE_FLAG_CANCEL, flags that the gesture event has been canceled.
  • MSGESTURE_FLAG_INERTIA , flags when the computer is in its inertia phase.

For example, if a user swipes their finger on the screen, the events and details will respond like this:

  • The MSGestureStart event fires along with the MSGESTURE_FLAG_BEGIN flag.
  • As the user moves their finger, the MSGestureChange event fires repeatedly with the MSGESTURE_FLAG_NONE being passed through the detail property.
  • When the user lifts their finger, the MSInertiaStart event fires, passing the MSGESTURE_FLAG_INERTIA flag.
  • As long as the element is still moving on the screen, the MSGestureChange element continues to fire with the MSGESTURE_FLAG_INERTIA flag being passed.
  • When the movement comes to an end, the MSGestureEnd event fires and two flags, MSGESTURE_FLAG_INERTIA and MSGESTURE_FLAG_END, are passed with the detail property.

If a user touches the screen and holds for a few seconds, and then moves their finger, the events and details will go like this:

  • After several seconds, the MSGestureHold event fires, passing the MSGESTURE_FLAG_BEGIN flag.
  • When the user starts moving their finger, the MSGestureHold event fires, passing MSGESTURE_FLAG_END and the MSGESTURE_FLAG_CANCEL flags. This signals that the hold has been canceled.
  • As the user moves their finger, the MSGestureChange event fires repeatedly as the MSGESTURE_FLAG_NONE is passed through the detail property. From here, the steps continue like in the previous sequence.
  • When the user lifts their finger, the MSInertiaStart event fires, passing the MSGESTURE_FLAG_INERTIA flag.
  • As long as the element is still moving on the screen, the MSGestureChange element continues to fire with the MSGESTURE_FLAG_INERTIA flag being passed.
  • When the movement comes to an end, the MSGestureEnd event fires and two flags, MSGESTURE_FLAG_INERTIA and MSGESTURE_FLAG_END, are passed with the detail property.

For a complete sample app that shows gesture events in action, see the MSGesture reference topic.

Gesture Events

Pointer Events