Files
reference/EventsOfPolymer.md
2026-08-04 15:32:57 +06:30

6.6 KiB
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.