Skip to content

Commit d07f3d6

Browse files
authored
Merge branch 'main' into dependabot/npm_and_yarn/follow-redirects-1.14.9
2 parents 741f5f2 + 6f595c3 commit d07f3d6

1 file changed

Lines changed: 57 additions & 0 deletions

File tree

docs/_guide/patterns.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,29 @@ class FuzzySearchElement extends HTMLElement {
2929
}
3030
```
3131

32+
Alternatively, if you'd like more precise control over the exact way debouncing happens (for example you'd like to make the debounce timeout dynamic, or sometimes call _without_ debouncing), you can have two methods following the pattern of `foo`/`fooNow` or `foo`/`fooSync`, where the non-suffixed method dispatches asynchronously to the `Now`/`Sync` suffixed method, a little like this:
33+
34+
```typescript
35+
import {controller} from '@github/catalyst'
36+
37+
@controller
38+
class FuzzySearchElement extends HTMLElement {
39+
40+
#searchAnimationFrame = 0
41+
search(event: Event) {
42+
clearAnimationFrame(this.#searchAnimationFrame)
43+
this.#searchAnimationFrame = requestAnimationFrame(() => this.searchNow(event: Event))
44+
}
45+
46+
searchNow(event: Event) {
47+
const value = event.currentTarget.value
48+
// This function is very computationally intensive, so we should run it as little as possible
49+
this.filterAllItemsWithValue(value)
50+
}
51+
52+
}
53+
```
54+
3255
### Aborting Network Requests
3356

3457
When making network requests using `fetch`, based on user input, you can cancel old requests as new ones come in. This is useful for performance as well as UI responsiveness, as old requests that aren't cancelled might complete later than newer ones, and causing the UI to jump around. Aborting network requests requires you to use [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) (a web platform feature).
@@ -70,3 +93,37 @@ class RemoveSearchElement extends HTMLElement {
7093
}
7194
}
7295
```
96+
97+
### Registering global or many event listeners
98+
99+
Generally speaking, you'll want to use ["Actions"]({{ site.baseurl }}/guide/actions) to register event listeners with your Controller, but Actions only work for components nested within your Controller. It may also be necessary to listen for events on the Document, Window, or across well-known adjacent elements. We can manually call `addEventListener` for these types, including during the `connectedCallback` phase. Cleanup for `addEventListener` can be a bit error prone, but [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) can be useful here to pass a signal that the element is cleaning up:
100+
101+
102+
```typescript
103+
@controller
104+
class UnsavedChangesElement extends HTMLElement {
105+
106+
#eventAbortController: AbortController|null
107+
108+
connectedCallback(event: Event) {
109+
// Create the new AbortController and get the new signal
110+
const {signal} = (this.#eventAbortController = new AbortController())
111+
112+
// You can `signal` as an option to any `addEventListener` call:
113+
window.addEventListener('hashchange', this, { signal })
114+
window.addEventListener('blur', this, { signal })
115+
window.addEventListener('popstate', this, { signal })
116+
window.addEventListener('pagehide', this, { signal })
117+
}
118+
119+
disconnectedCallback() {
120+
// This will clean up any `addEventListener` calls which were given the `signal`
121+
this.#eventAbortController?.abort()
122+
}
123+
124+
handleEvent(event) {
125+
// `handleEvent` will be called when each one of the event listeners
126+
// defined in `connectedCallback` is dispatched.
127+
}
128+
}
129+
```

0 commit comments

Comments
 (0)