-
Notifications
You must be signed in to change notification settings - Fork 33
Events
Add event listeners to the host element by providing a @Listen('event-name
)`
annotation to any method.
You can also add an event listener to any element in the $
collection
using the syntax nodeId.eventName.
Example:
x_custom.html:
<dom-module id="x-custom">
<template>
<div>I will respond</div>
<div>to a tap on</div>
<div>any of my children!</div>
<div id="special">I am special!</div>
</template>
</dom-module>
x_custom.dart:
@PolymerRegister('x-custom')
class XCustom extends PolymerElement {
XCustom.created() : super.created();
@Listen('tap')
void regularTap(event, [_]) {
window.alert('Thank you for tapping');
}
@Listen('special.tap')
void specialTap(event, [_]) {
window.alert('It was special tapping');
}
}
To add event listeners to local-DOM children, use
on-event
annotations in your template. This often
eliminates the need to give an element an id
solely for the purpose of
binding an event listener. For now you must also annotate the method with
@reflectable
to make those methods available.
Example:
x_custom.html:
<dom-module id="x-custom">
<template>
<button on-click="handleClick">Kick Me</button>
</template>
</dom-module>
x_custom.dart:
@PolymerRegister('x-custom')
class XCustom extends PolymerElement {
XCustom.created() : super.created();
@reflectable
handleClick(event, [_]) {
window.alert('Ow!');
}
}
Because the event name is specified using an HTML attribute, the event name is always
converted to lowercase. This is because HTML attribute names are case
insensitive. So specifying on-myEvent
adds a listener for myevent
. The event handler
name (for example, handleClick
) is case sensitive.
Compatibility note: The syntax differs from 0.5, which required curly brackets ({{}}) around the event handler name.
Lowercase event names. When you use a declarative handler, the event name
is converted to lowercase, because attributes are case-insensitive.
So the attribute on-core-signal-newData
sets up a listener for core-signal-newdata
,
not core-signal-newData
. To avoid confusion, always use lowercase event names.
{: .alert .alert-info }
If you want to do your own custom event listeners (using on['some-event'].listen(...)
) then you will most likely need to call convertToDart
on the event you receive in order to have access to all its properties. This is because any event fired from polymer (or the fire
method) is actually a JS event. Remember that when setting up your own event listeners you will also need to clean them up, otherwise you will get memory leaks.
@PolymerRegister('x-custom')
class XCustom extends PolymerElement {
XCustom.created() : super.created();
StreamSubscription _clickSubscription;
attached() {
_clickSubscription = this.on['tap'].listen((e) {
e = convertToDart(e);
// Read things from `e`.
});
}
detached() {
// Always cancel your event subscriptions!!!
_clickSubscription.cancel();
}
}
Polymer fires a custom "gesture" events for certain user
interactions automatically when a declarative listener is added for the event
type. 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. For example, tap
should be used instead of
click
for the most reliable cross-platform results.
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
.
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 event -
y
- clientY coordinate for event -
sourceEvent
- the original DOM event that caused thedown
action
-
-
up - finger/button went up
-
x
- clientX coordinate for event -
y
- clientY coordinate for event -
sourceEvent
- the original DOM event that caused theup
action
-
-
tap - down & up occurred
-
x
- clientX coordinate for event -
y
- clientY coordinate for event -
sourceEvent
- the original DOM event that caused thetap
action
-
-
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 tracking -
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:
drag_me.html:
<dom-module id="drag-me">
<style>
#dragme {
width: 500px;
height: 500px;
background: gray;
}
</style>
<template>
<div id="dragme" on-track="handleTrack">{{message}}</div>
</template>
</dom-module>
drag_me.dart:
@PolymerRegister('drag-me')
class DragMe extends PolymerElement {
DragMe.created() : super.created();
@property
String message;
@reflectable
void handleTrack(e, detail) {
switch(detail['state']) {
case 'start':
message = 'Tracking started!';
break;
case 'track':
message = 'Tracking in progress... ${detail['x']}, ${detail['y']}';
break;
case 'end':
message = 'Tracking ended!';
break;
}
notifyPath('message', message);
}
}
Example with @Listen
:
drag_me.html:
<dom-module id="drag-me">
<style>
#dragme {
width: 500px;
height: 500px;
background: gray;
}
</style>
<template>
<div id="dragme">{{message}}</div>
</template>
</dom-module>
drag_me.dart:
@PolymerRegister('drag-me')
class DragMe extends PolymerElement {
DragMe.created() : super.created();
@property
String message;
@Listen('dragme.track')
void handleTrack(e, detail) {
switch(detail['state']) {
case 'start':
message = 'Tracking started!';
break;
case 'track':
message = 'Tracking in progress... ${detail['x']}, ${detail['y']}';
break;
case 'end':
message = 'Tracking ended!';
break;
}
notifyPath('message', message);
}
}
Shadow DOM has a feature called "event retargeting" which changes an event's target as it bubbles up, such that target is always in the receiving element's light DOM. Shady DOM does not do event retargeting, so events may behave differently depending on which local DOM system is in use.
Use Polymer.dom(event)
to get a normalized event object that provides
equivalent target data on both shady DOM and shadow DOM. Specifically, the
normalized event has the following properties:
-
rootTarget
: The original or root target before shadow retargeting (equivalent toevent.path[0]
under shadow DOM orevent.target
under shady DOM). -
localTarget
: Retargeted event target (equivalent toevent.target
under shadow DOM) -
path
: Array of nodes through which event will pass (equivalent toevent.path
under shadow DOM).