mirror of https://github.com/sveltejs/svelte
parent
e4f7a592ca
commit
80a393cdb2
@ -0,0 +1,35 @@
|
||||
<script>
|
||||
let text = `Select some text and hit the tab key to toggle uppercase`;
|
||||
|
||||
async function handleKeydown(event) {
|
||||
if (event.which !== 9) return;
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
const { selectionStart, selectionEnd, value } = this;
|
||||
const selection = value.slice(selectionStart, selectionEnd);
|
||||
|
||||
const replacement = /[a-z]/.test(selection)
|
||||
? selection.toUpperCase()
|
||||
: selection.toLowerCase();
|
||||
|
||||
text = (
|
||||
value.slice(0, selectionStart) +
|
||||
replacement +
|
||||
value.slice(selectionEnd)
|
||||
);
|
||||
|
||||
// this has no effect, because the DOM hasn't updated yet
|
||||
this.selectionStart = selectionStart;
|
||||
this.selectionEnd = selectionEnd;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
textarea {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<textarea value={text} on:keydown={handleKeydown}></textarea>
|
@ -0,0 +1,37 @@
|
||||
<script>
|
||||
import { tick } from 'svelte';
|
||||
|
||||
let text = `Select some text and hit the tab key to toggle uppercase`;
|
||||
|
||||
async function handleKeydown(event) {
|
||||
if (event.which !== 9) return;
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
const { selectionStart, selectionEnd, value } = this;
|
||||
const selection = value.slice(selectionStart, selectionEnd);
|
||||
|
||||
const replacement = /[a-z]/.test(selection)
|
||||
? selection.toUpperCase()
|
||||
: selection.toLowerCase();
|
||||
|
||||
text = (
|
||||
value.slice(0, selectionStart) +
|
||||
replacement +
|
||||
value.slice(selectionEnd)
|
||||
);
|
||||
|
||||
await tick();
|
||||
this.selectionStart = selectionStart;
|
||||
this.selectionEnd = selectionEnd;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
textarea {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<textarea value={text} on:keydown={handleKeydown}></textarea>
|
@ -0,0 +1,21 @@
|
||||
---
|
||||
title: tick
|
||||
---
|
||||
|
||||
The `tick` function is unlike other lifecycle functions in that you can call it any time, not just when the component first initialises. It returns a promise that resolves as soon as any pending state changes have been applied to the DOM (or immediately, if there are no pending state changes).
|
||||
|
||||
When you invalidate component state in Svelte, it doesn't update the DOM immediately. Instead, it waits until the next *microtask* to see if there are any other changes that need to be applied, including in other components. Doing so avoids unnecessary work and allows the browser to batch things more effectively.
|
||||
|
||||
You can see that behaviour in this example. Select a range of text and hit the tab key. Because the `<textarea>` value changes, the current selection is cleared and the cursor jumps, annoyingly, to the end. We can fix this by importing `tick`...
|
||||
|
||||
```js
|
||||
import { tick } from 'svelte';
|
||||
```
|
||||
|
||||
...and running it immediately before we set `this.selectionStart` and `this.selectionEnd` at the end of `handleKeydown`:
|
||||
|
||||
```js
|
||||
await tick();
|
||||
this.selectionStart = selectionStart;
|
||||
this.selectionEnd = selectionEnd;
|
||||
```
|
Loading…
Reference in new issue