199 lines
6.6 KiB
Markdown
Executable File
199 lines
6.6 KiB
Markdown
Executable File
# Add and Remove Listeners
|
|
|
|
ready() {
|
|
super.ready();
|
|
this.addEventListener('click', e => this._myClickListener(e));
|
|
}
|
|
The previous example uses an arrow function to ensure the listener is called with the element as the this value. You can also use bind to create a bound instance of the listener function. This can be useful if you need to remove the listener.
|
|
|
|
constructor() {
|
|
super();
|
|
this._boundListener = this._myLocationListener.bind(this);
|
|
}
|
|
|
|
connectedCallback() {
|
|
super.connectedCallback();
|
|
window.addEventListener('hashchange', this._boundListener);
|
|
}
|
|
|
|
disconnectedCallback() {
|
|
super.disconnectedCallback();
|
|
window.removeEventListener('hashchange', this._boundListener);
|
|
}
|
|
|
|
# Fire custom events
|
|
|
|
To fire a custom event from the host element use the standard CustomEvent constructor and the dispatchEvent method.
|
|
|
|
x-custom.js
|
|
|
|
class XCustom extends PolymerElement {
|
|
static get template(){
|
|
return html`
|
|
<button on-click="handleClick">Kick Me</button>
|
|
`;
|
|
}
|
|
handleClick(e) {
|
|
this.dispatchEvent(new CustomEvent('kick', {detail: {kicked: true}}));
|
|
}
|
|
}
|
|
customElements.define('x-custom', XCustom);
|
|
|
|
index.html
|
|
|
|
<x-custom></x-custom>
|
|
|
|
<script>
|
|
document.querySelector('x-custom').addEventListener('kick', function (e) {
|
|
console.log(e.detail.kicked); // true
|
|
})
|
|
</script>
|
|
|
|
|
|
To make a custom event pass through shadow DOM boundaries, set the composed flag to true when you create the event:
|
|
|
|
|
|
var event = new CustomEvent('my-event', {bubbles: true, composed: true});
|
|
|
|
# Handle Retargeted events
|
|
The event's composedPath() method returns an array of nodes through which the event will pass. So event.composedPath()[0] represents the original target for the event (unless that target is hidden in a closed shadow root).
|
|
|
|
event-retargeting.js
|
|
|
|
class EventRetargeting extends PolymerElement {
|
|
static get template(){
|
|
return html`
|
|
<button id="myButton">Click Me</button>
|
|
`;
|
|
}
|
|
ready() {
|
|
super.ready();
|
|
this.$.myButton.addEventListener('click', e => {this._handleClick(e)});
|
|
}
|
|
|
|
_handleClick(e) {
|
|
console.info(e.target.id + ' was clicked.');
|
|
}
|
|
}
|
|
customElements.define('event-retargeting', EventRetargeting);
|
|
|
|
index.html
|
|
|
|
<event-retargeting></event-retargeting>
|
|
|
|
<script>
|
|
var el = document.querySelector('event-retargeting');
|
|
el.addEventListener('click', function(e){
|
|
// logs the instance of event-targeting that hosts #myButton
|
|
console.info('target is:', e.target);
|
|
// logs [#myButton, ShadowRoot, event-retargeting,
|
|
// body, html, document, Window]
|
|
console.info('composedPath is:', e.composedPath());
|
|
});
|
|
</script>
|
|
|
|
|
|
# Using gesture event
|
|
|
|
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>
|
|
|
|
## 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:
|
|
|
|
1 . down—finger/button went down
|
|
x—clientX coordinate for event
|
|
y—clientY coordinate for event
|
|
sourceEvent—the original DOM event that caused the down action
|
|
2 . up—finger/button went up
|
|
x—clientX coordinate for event
|
|
y—clientY coordinate for event
|
|
sourceEvent—the original DOM event that caused the up action
|
|
3 . tap—down & up occurred
|
|
x—clientX coordinate for event
|
|
y—clientY coordinate for event
|
|
sourceEvent—the original DOM event that caused the tap action
|
|
4 . track—moving while finger/button is down
|
|
1. state—a string indicating the tracking state:
|
|
2. start—fired when tracking is first detected (finger/button down and moved past a pre-set distance threshold)
|
|
track—fired while tracking
|
|
3. end—fired when tracking ends
|
|
x—clientX coordinate for event
|
|
y—clientY coordinate for event
|
|
dx—change in pixels horizontally since the first track event
|
|
dy—change in pixels vertically since the first track event
|
|
ddx—change in pixels horizontally since last track event
|
|
ddy—change in pixels vertically since last track event
|
|
hover()—a function that may be called to determine the element currently being hovered
|
|
|
|
Example,
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#### Example imperative event listener
|
|
|
|
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.
|