https://github.com/ember-polyfills/ember-on-modifier
Implements the `{{on eventName this.someAction}}` element modifier from https://github.com/emberjs/rfcs/blob/master/text/0471-on-modifier.md
https://github.com/ember-polyfills/ember-on-modifier
ember ember-addon ember-element-modifier ember-modifier emberjs polyfill
Last synced: about 2 months ago
JSON representation
Implements the `{{on eventName this.someAction}}` element modifier from https://github.com/emberjs/rfcs/blob/master/text/0471-on-modifier.md
- Host: GitHub
- URL: https://github.com/ember-polyfills/ember-on-modifier
- Owner: ember-polyfills
- License: mit
- Created: 2019-01-29T19:47:40.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2022-12-10T16:52:39.000Z (over 3 years ago)
- Last Synced: 2026-02-06T00:30:29.574Z (2 months ago)
- Topics: ember, ember-addon, ember-element-modifier, ember-modifier, emberjs, polyfill
- Language: JavaScript
- Homepage:
- Size: 1.76 MB
- Stars: 36
- Watchers: 2
- Forks: 6
- Open Issues: 41
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE.md
Awesome Lists containing this project
- awesome-ember - ember-on-modifier - An implementation of the `{{on}}` element modifier shown in the Modifiers RFC #353. (Packages / Modifiers)
README
# ember-on-modifier
[](https://travis-ci.org/buschtoens/ember-on-modifier)
[](http://badge.fury.io/js/ember-on-modifier)
[](http://badge.fury.io/js/ember-on-modifier)
[](https://emberobserver.com/addons/ember-on-modifier)
[](https://travis-ci.org/buschtoens/ember-on-modifier)
[](https://travis-ci.org/buschtoens/ember-on-modifier)
[](https://github.com/prettier/prettier)
[](https://david-dm.org/buschtoens/ember-on-modifier)
[](https://david-dm.org/buschtoens/ember-on-modifier)
A polyfill for the `{{on}}` element modifier specified by
[RFC #471 "`{{on}}` modifier"](https://github.com/emberjs/rfcs/blob/master/text/0471-on-modifier.md).
## Installation
```
ember install ember-on-modifier
```
## Compatibility
* Completely inert when running `ember-source` 3.11 or higher
* Tested against `ember-source` v2.12, v2.18, v3.4 in CI
## Usage
```hbs
Click me baby, one more time!
```
```ts
import Component from '@ember/component';
import { action } from '@ember-decorators/object';
export default class BritneySpearsComponent extends Component {
@action
onClick(event: MouseEvent) {
console.log('I must confess, I still believe.');
}
}
```
The [`@action` decorator][@action] is used to bind the `onClick` method to the
component instance.
[@action]: https://github.com/emberjs/rfcs/blob/master/text/0408-decorators.md#method-binding
This is essentially equivalent to:
```ts
didInsertElement() {
super.didInsertElement();
const button = this.element.querySelector('button');
button.addEventListener('click', this.onClick);
}
```
In addition to the above `{{on}}` will properly tear down the event listener,
when the element is removed from the DOM. It will also re-register the event
listener, if any of the passed parameters change.
### Listening to Multiple Events
You can use the `{{on}}` modifier multiple times on the same element, even for
the same event.
```hbs
Click me baby, one more time!
```
### Event Options
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
Lorem Ipsum ...
```
This is essentially equivalent to:
```ts
didInsertElement() {
super.didInsertElement();
const div = this.element.querySelector('div');
div.addEventListener('scroll', this.onScroll, { passive: true });
}
```
#### `once`
To fire an event listener only once, you can pass the [`once` option][addeventlistener-parameters]:
```hbs
Click me baby, one more time!
```
`clickOnlyTheFirstTime` will only be fired the first time the button is clicked.
`clickEveryTime` is fired every time the button 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
Click me baby, one more time!
```
#### `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
Lorem ipsum...
```
#### Internet Explorer 11 Support
Internet Explorer 11 has a buggy and incomplete implementation of
`addEventListener`: It does not accept an
[`options`][addeventlistener-parameters] parameter and _sometimes_ even throws
a cryptic error when passing options.
This is why this addon ships a tiny [ponyfill][ponyfill] for `addEventLisener`
that is used internally to emulate the `once`, `capture` and `passive` option.
This means that all currently known [`options`][addeventlistener-parameters] are
polyfilled, so that you can rely on them in your logic.
[ponyfill]: https://github.com/sindresorhus/ponyfill
### Currying / Partial Application
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.users as |user|}}
Delete {{user.name}}
{{/each}}
```
```ts
import Component from '@ember/component';
import { action } from '@ember-decorators/object';
interface User {
name: string;
}
export default class UserListComponent extends Component {
users: User[] = [{ name: 'Tom Dale' }, { name: 'Yehuda Katz' }];
@action
deleteUser(user: User, event: MouseEvent) {
event.preventDefault();
this.users.removeObject(user);
}
}
```
### `preventDefault` / `stopPropagation` / `stopImmediatePropagation`
The old [`{{action}}` modifier][action-event-propagation] used to allow easily
calling `event.preventDefault()` 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
```
## Related Projects
- **[`ember-on-helper`][ember-on-helper]:** A complimentary `{{on}` template
helper that accepts arbitrary event targets.
```hbs
{{on eventTarget eventName eventListener}}
```
Also ships with two convenience helpers for adding event listeners to
`document` and `window`:
```hbs
{{on-document eventName eventListener}}
{{on-window eventName eventListener}}
```
[ember-on-helper]: https://github.com/buschtoens/ember-on-helper