Polymer provides optional support for custom "gesture" events for certain user interactions. These events fire consistently on both touch and mouse environments, so we recommend using these events instead of their mouse- or touch-specific event counterparts. This provides better interoperability with both touch and mouse devices.
In general, use the standard click event instead of tap in mobile browsers. The tap
event is included in the gesture event mixin for backwards compatibility, but it's no longer
required in modern mobile browsers.
Using gesture events
Add gesture support by importing and using the GestureEventListeners mixin:
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
class UsingGestures extends GestureEventListeners(PolymerElement){
...
}
Gesture events require some extra setup, so you can't simply add a listener
using the generic addEventListener method. To listen for a gesture event:
-
Use an annotated event listener for one of the gesture events.
<div on-tap="tapHandler">Tap here!</div>Polymer automatically does the extra bookkeeping for gesture events when you use annotated event listeners.
-
Use the
addListener/removeListenermethods from thegesturesmodule (@polymer/polymer/lib/utils/gestures.js).import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js'; import * as Gestures from '@polymer/polymer/lib/utils/gestures.js'; class UsingGestures extends GestureEventListeners(PolymerElement){ constructor(){ super(); Gestures.addListener(this, 'tap', this.tapHandler.bind(this)); } ... disconnectedCallback() { super.disconnectedCallback(); Gestures.removeListener(this, 'tap', this.tapHandler.bind(this)); } }You can use the
addListenerfunction to add a listener to the host element.
Gesture event types
The following are the gesture event types supported, with a short description
and list of detail properties available on event.detail for each type:
- down—finger/button went down
x—clientX coordinate for eventy—clientY coordinate for eventsourceEvent—the original DOM event that caused thedownaction
- up—finger/button went up
x—clientX coordinate for eventy—clientY coordinate for eventsourceEvent—the original DOM event that caused theupaction
- tap—down & up occurred
x—clientX coordinate for eventy—clientY coordinate for eventsourceEvent—the original DOM event that caused thetapaction
- track—moving while finger/button is down
state—a string indicating the tracking state:start—fired when tracking is first detected (finger/button down and moved past a pre-set distance threshold)track—fired while trackingend—fired when tracking ends
x—clientX coordinate for eventy—clientY coordinate for eventdx—change in pixels horizontally since the first track eventdy—change in pixels vertically since the first track eventddx—change in pixels horizontally since last track eventddy—change in pixels vertically since last track eventhover()—a function that may be called to determine the element currently being hovered
Examples
Example declarative event listener
import {PolymerElement, html} from '@polymer/polymer/polymer-element.js';
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
class DragMe extends GestureEventListeners(PolymerElement){
static get template(){
return html`
<style>
#dragme {
width: 500px;
height: 500px;
background: lightgray;
}
</style>
<div id="dragme" on-track="handleTrack">[[message]]</div>
`;
}
handleTrack(e) {
switch(e.detail.state) {
case 'start':
this.message = 'Tracking started!';
break;
case 'track':
this.message = 'Tracking in progress... ' +
e.detail.x + ', ' + e.detail.y;
break;
case 'end':
this.message = 'Tracking ended!';
break;
}
}
}
customElements.define('drag-me', DragMe);
Example imperative event listener
This example uses the addListener method from the gestures module to add a listener to the host element, which can't be done with annotated event listeners. If the listener is attached to the host element or a shadow DOM child, you can usually add the event listener once and not worry about removing it.
If you are adding an event listener to a dynamically-added child, you may need to remove the event listener with the removeListener method from the gestures module when you remove the child, to allow the child element to be garbage collected.
import {PolymerElement, html} from '@polymer/polymer/polymer-element.js';
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
import * as Gestures from '@polymer/polymer/lib/utils/gestures.js';
class TapMe extends GestureEventListeners(PolymerElement){
static get template(){
return html`
<style>
:host {
display: block;
width: 200px;
height: 200px;
border: 1px solid blue;
}
</style>
<div>Tap me!</div>
<div>I've been tapped [[count]] times.</div>
`;
}
constructor() {
super();
this.count = 0;
Gestures.addListener(this, 'tap', this.handleTap.bind(this));
}
handleTap(e) {
this.count++;
}
}
customElements.define('tap-me', TapMe);
Gestures and scroll direction
Listening for certain gestures controls the scrolling direction for touch input.
For example, nodes with a listener for the track event will prevent scrolling
by default. Elements can override scroll direction with
this.setScrollDirection(direction, node), where direction is one of 'x',
'y', 'none', or 'all', and node defaults to this.