{{on eventTarget eventName someAction}} template helper
npm install ember-on-helper








An {{on}} template helper complimentary to the
RFC #471 "{{on}} modifier".
```
ember install ember-on-helper
#### Compatibility
- Ember.js v2.18 or above
- ember-cli v2.13 or above
You would use the {{on}} _modifier_ to register event listeners on elementsEventTarget
that are in the realm of your current template. But sometimes you need to
register event listeners on elements or even on generic s that aredocument
outside of the control of your template, e.g. or window.
> ⚠️👉 WARNING: Do not overuse this helper. If you want to bind to an
> element that _is_ controlled by Glimmer, but maybe just not by the current
> template, _do not_ reach for a manual document.querySelector(). Instead,Service
> think about your current template and state setup and try to use a true "Data
> Down, Actions Up" pattern or use a shared as a message bus.
Pretty much exactly the same as the {{on}} modifier, except for that the{{on}} helper expects one more positional parameter upfront: the evenTarget.
`hbs`
{{on eventTarget eventName eventListener}}
As with the {{on}} modifier, you can also pass optional event options as named
parameters:
`hbs`
{{on eventTarget eventName eventListener capture=bool once=bool passive=bool}}
`hbs
Click anywhere in the browser window, fam.
{{on this.document "click" this.onDocumentClick}}
`
`ts
import Component from '@glimmer/component';
import { action } from '@ember/object';
export default class TomstersWitnessComponent extends Component {
document = document;
@action
onDocumentClick(event: MouseEvent) {
console.log(
'Do you have a minute to talk about our Lord and Savior, Ember.js?'
);
}
}
`
This is essentially equivalent to:
`ts
didInsertElement() {
super.didInsertElement();
document.addEventListener('click', this.onDocumentClick);
}
`
In addition to the above {{on}} will properly tear down the event listener,
when the helper is removed from the DOM. It will also re-register the event
listener, if any of the passed parameters change.
The [@action decorator][@action] is used to bind the onDocumentClick methodthis
to the component instance. This is not strictly required here, since we do not
access , but in order to not break with established patterns, we do it
anyway.
[@action]: https://github.com/emberjs/rfcs/blob/master/text/0408-decorators.md#method-binding
You will often want to use the {{on}} helper to listen to events which arewindow
emitted on or document. Because providing access to these globals in{{on}}
the template as shown in [Simple Example][#simple-example] is quite
cumbersome, brings two friends to the party:
- {{on-document eventName eventListener}}{{on-window eventName eventListener}}
-
They work exactly the same way as {{on}} and also accept event options.
You can use the {{on}} helper multiple times in the same element, even for
the same event.
`hbs`
{{on this.someElement "click" this.onClick}}
{{on this.someElement "click" this.anotherOnClick}}
{{on this.someElement "mousemove" this.onMouseMove}}
All named parameters will be passed through to
[addEventListener][addeventlistener] as the third parameter, the options hash.
[addeventlistener]: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
`hbs`
{{on-document "scroll" this.onScroll passive=true}}
This is essentially equivalent to:
`ts
didInsertElement() {
super.didInsertElement();
document.addEventListener('scroll', this.onScroll, { passive: true });
}
`
#### once
To fire an event listener only once, you can pass the [once option][addeventlistener-parameters]:
`hbs`
{{on-window "click" this.clickOnlyTheFirstTime once=true}}
{{on-window "click" this.clickEveryTime}}
clickOnlyTheFirstTime will only be fired the first time the page is clicked.clickEveryTime is fired every time the page is clicked, including the first
time.
[addeventlistener-parameters]: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Parameters
#### capture
To listen for an event during the capture phase already, use the [capture option][addeventlistener-parameters]:
`hbs
{{on-document "click" this.triggeredFirst capture=true}}
`
#### passive
If true, you promise to not call event.preventDefault(). This allows the
browser to optimize the processing of this event and not block the UI thread.
This prevent scroll jank.
If you still call event.preventDefault(), an assertion will be raised.
`hbs`
{{on-document "scroll" this.trackScrollPosition passive=true}}>
#### Internet Explorer 11 Support
Internet Explorer 11 has a buggy and incomplete implementation of
addEventListener: It does not accept anoptions
[][addeventlistener-parameters] parameter and _sometimes_ even throws
a cryptic error when passing options.
This is why this addon ships a tiny [ponyfill][ponyfill] for addEventLiseneronce
that is used internally to emulate the , capture and passive option.options
This means that all currently known [][addeventlistener-parameters] are
polyfilled, so that you can rely on them in your logic.
[ponyfill]: https://github.com/sindresorhus/ponyfill
If you want to curry the function call / partially apply arguments, you can do
so using the [{{fn}} helper][fn-helper]:
[fn-helper]: https://github.com/emberjs/rfcs/blob/master/text/0470-fn-helper.md
`hbs`
{{#each this.videos as |video|}}
{{on video.element "play" (fn this.onPlay video)}}
{{on video.element "pause" (fn this.onPause video)}}
{{/each}}
`ts
import Component from '@ember/component';
import { action } from '@ember-decorators/object';
interface Video {
element: HTMLVideoElement;
title: string;
}
export default class UserListComponent extends Component {
videos: Video[];
@action
onPlay(video: Video, event: MouseEvent) {
console.log(Started playing '${video.title}'.);
}
@action
onPlay(video: Video, event: MouseEvent) {
console.log(Paused '${video.title}'.);`
}
}
The old [{{action}} modifier][action-event-propagation] used to allow easilyevent.preventDefault()
calling like so:
`hbs`
Click me
[action-event-propagation]: https://www.emberjs.com/api/ember/release/classes/Ember.Templates.helpers/methods/action?anchor=action#event-propagation
You also could easily call event.stopPropagation() to avoid bubbling like so:
`hbs`
Click me
You can still do this using [ember-event-helpers][ember-event-helpers]:
[ember-event-helpers]: https://github.com/buschtoens/ember-event-helpers
`hbs`
Click me
`hbs`
Click me
This addon is a straight copy of [ember-on-modifier][ember-on-modifier], the{{on}}` modifier.
polyfill for the
[ember-on-modifier]: https://github.com/buschtoens/ember-on-modifier