72

I'm trying to learn how to work with the Aurelia framework. In doing so, I was reading the documentation here regarding their method of binding events. The documentation suggests using delegate by default. I have forked the plunkr that they provided in one of their blog posts and added a little bit to it. The full plunk is here.


app.html

<template>
    <input value.bind="pageInput" blur.delegate="showAlert()" placeholder="delegate()" />
    <input value.bind="pageInput" blur.trigger="showAlert()" placeholder="trigger()" />

    <button type="button" click.delegate="showAlert()">delegate()</button>
    <button type="button" click.trigger="showAlert()">trigger()</button>
</template>

app.js

export class App {
  showAlert() {
    alert('showAlert()');
  }
}

As you can see in the plunkr, the blur.trigger/click.delegate/click.trigger all fire the event, but blur.delegate doesn't.

Why is this the case?

How can you determine when .delegate isn't going to work(without manually testing it of course)?

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
peinearydevelopment
  • 11,042
  • 5
  • 48
  • 76

2 Answers2

109

Use delegate except when you cannot use delegate.

Event delegation is a technique used to improve application performance. It drastically reduces the number of event subscriptions by leveraging the "bubbling" characteristic of most DOM events. With event delegation, handlers are not attached to individual elements. Instead, a single event handler is attached to a top-level node such as the body element. When an event bubbles up to this shared top-level handler the event delegation logic calls the appropriate handler based on the event's target.

To find out if event delegation can be used with a particular event, google mdn [event name] event. In fact, preceding any web platform related google search with mdn often returns a high quality result from the Mozilla Developer Network. Once you're on the event's MDN page, check whether the event bubbles. Only events that bubble can be used with Aurelia's delegate binding command. The blur, focus, load and unload events do not bubble so you'll need to use the trigger binding command to subscribe to these events.

Here's the MDN page for blur. It has further info on event delegation techniques for the blur and focus events.

Exceptions to the general guidance above:

Use trigger on buttons when the following conditions are met:

  1. You need to disable the button.
  2. The button's content is made up of other elements (as opposed to just text).

This will ensure clicks on disabled button's children won't bubble up to the delegate event handler. More info here.

Use trigger for click in certain iOS use-cases:

iOS does not bubble click events on elements other than a, button, input and select. If you're subscribing to click on a non-input element like a div and are targeting iOS, use the trigger binding command. More info here and here.

Community
  • 1
  • 1
Jeremy Danyow
  • 26,470
  • 12
  • 87
  • 133
  • 3
    Additional reason to use trigger: If you are supporting Internet Explorer and you set your button to `disabled`, then you need to have your `click` event be a `trigger`, not a `delegate`. If you use `delegate`, then the `click` event will still fire when the button is clicked on, even if the button is disabled. See this issue for more details: https://github.com/aurelia/binding/issues/163 – Vaccano Apr 21 '16 at 19:06
  • I disagree with the documentation here. There are gotchas with delegate that don't exist with trigger. I would argue that a disabled button firing events unexpectedly or buttons outright not working on iOS is a bigger problem than perf for most apps, especially when you're talking about a handful of elements. Working on a table with tons of rows? Carefully consider delegate. Otherwise, safer to go with trigger. – mgiesa Feb 27 '17 at 03:34
  • Why is trigger.click recommended over setting cursor: pointer on the element? – Dan Pettersson Jun 07 '17 at 19:48
  • What does `bubbles` mean? https://stackoverflow.com/questions/4616694/what-is-event-bubbling-and-capturing – Cirelli94 Feb 06 '18 at 15:25
1

Regarding to this, blur delegate would work if Aurelia listens to the event in capture phase, but this is not doable atm in Aurelia. Wold be interesting if someone could provide some hint how to capture event in Aurelia

In that case, following will work:

<template>
    <input blur.delegate-capture='showAlert()' />
</template>
bigopon
  • 1,924
  • 2
  • 14
  • 23
  • 2
    here's a prototype of how a `capture` binding command to go along with `delegate` and `trigger` might be added to aurelia: https://gist.run/?id=196c99652a28d571527a8fff63297308 – Jeremy Danyow Oct 26 '16 at 14:05
  • Is this on its way into official ? – bigopon Oct 26 '16 at 20:59
  • 2
    To anyone coming to this question, the capture binding command is now official built in. syntax is `click.capture='expression'` – bigopon Dec 16 '16 at 12:32