Время чтения: 2 мин.
В этой статье я покажу, как создать полезный хук useCaretRestore
, который сохраняет позицию курсора при изменении содержимого input-полей. Это особенно полезно при работе с текстовыми редакторами, формами и другими элементами ввода.
Зачем нужен этот хук?
Когда мы программно изменяем значение input-поля, курсор обычно перескакивает в конец. Это раздражает пользователей, особенно если они редактируют текст в середине поля. Наш хук решает эту проблему.
Реализация хука
Создадим файл useCaretRestore.ts
:
import { nextTick } from 'vue'
import type { Ref } from 'vue'
export function useCaretRestore(inputRef: Ref<HTMLInputElement | null>) {
function withCaretRestore(callback: () => void) {
// Запоминаем текущую позицию курсора
const caretPosition = inputRef.value?.selectionStart
// Если поле не существует, ничего не делаем
if (caretPosition === undefined) return
// Выполняем переданную функцию
callback()
// После обновления DOM возвращаем курсор на место
nextTick(() => {
inputRef.value?.setSelectionRange(caretPosition, caretPosition)
})
}
return { withCaretRestore }
}
Простые примеры использования
1. Вставка текста по кнопке
Добавим кнопку для вставки стандартного текста:
<script setup>
import { ref } from 'vue'
import { useCaretRestore } from './useCaretRestore'
const inputRef = ref(null)
const message = ref('')
const { withCaretRestore } = useCaretRestore(inputRef)
function insertGreeting() {
withCaretRestore(() => {
message.value += 'Здравствуйте! '
})
}
</script>
<template>
<input ref="inputRef" v-model="message" placeholder="Введите сообщение">
<button @click="insertGreeting">Добавить приветствие</button>
</template>
2. Вставка смайликов
Создадим кнопки для быстрой вставки эмодзи:
<script setup>
const comment = ref('')
const inputRef = ref(null)
const { withCaretRestore } = useCaretRestore(inputRef)
function insertEmoji(emoji: string) {
withCaretRestore(() => {
comment.value += emoji
})
}
</script>
<template>
<input ref="inputRef" v-model="comment" placeholder="Оставьте комментарий">
<button @click="insertEmoji('😊')">😊</button>
<button @click="insertEmoji('👍')">👍</button>
<button @click="insertEmoji('❤️')">❤️</button>
</template>
Как это работает?
- Когда пользователь нажимает кнопку, хук запоминает текущее положение курсора
- Выполняется переданная функция (например, вставка текста)
- После обновления DOM хук возвращает курсор на прежнюю позицию
Преимущества нашего решения
- Простота использования: Достаточно обернуть изменение в
withCaretRestore
- Универсальность: Работает с любыми input-элементами
- Автоматическая очистка: Не нужно беспокоиться о подписках на события
Заключение
Хук useCaretRestore
— это небольшой, но полезный инструмент, который сделает работу с формами более удобной для пользователей. Попробуйте использовать его в своих проектах!
Добавить комментарий