Использование localStorage в связке с Awesomplete
позволяет реализовать устойчивые сценарии автодополнения, основанные на
истории ввода, пользовательских предпочтениях и локальном кэше данных.
Это особенно важно для снижения количества сетевых запросов, ускорения
отображения подсказок и сохранения пользовательского контекста между
сессиями.
Awesomplete принимает массив строк или объектов в качестве источника
данных. localStorage может выступать промежуточным слоем
хранения, который сохраняет этот массив между перезагрузками
страницы.
const input = document.querySelector("#search");
const stored = localStorage.getItem("awesomplete-data");
const list = stored ? JSON.parse(stored) : [];
const awesomplete = new Awesomplete(input, {
list: list
});
На данном этапе реализуется простая схема: при инициализации компонента данные берутся из локального хранилища и передаются в Awesomplete.
Частый сценарий — накопление истории запросов пользователя. Это позволяет формировать персонализированные подсказки.
function saveToStorage(value) {
const key = "awesomplete-data";
const stored = localStorage.getItem(key);
let list = stored ? JSON.parse(stored) : [];
if (!list.includes(value)) {
list.push(value);
}
localStorage.setItem(key, JSON.stringify(list));
}
Функция выполняет три ключевые операции:
localStorage.Awesomplete предоставляет событие
awesomplete-selectcomplete, которое срабатывает при выборе
подсказки. Это оптимальная точка для записи данных.
input.addEventListener("awesomplete-selectcomplete", function () {
saveToStorage(this.value);
});
В данном случае сохраняется уже выбранное значение, что позволяет формировать более точную историю пользовательских действий.
localStorage имеет ограничение по объёму (обычно около
5–10 МБ), поэтому хранение неограниченного массива недопустимо.
Необходимо вводить ограничение длины списка.
function saveToStorage(value) {
const key = "awesomplete-data";
const stored = localStorage.getItem(key);
let list = stored ? JSON.parse(stored) : [];
if (!list.includes(value)) {
list.unshift(value);
}
if (list.length > 20) {
list = list.slice(0, 20);
}
localStorage.setItem(key, JSON.stringify(list));
}
Использование unshift позволяет сохранять наиболее
свежие значения в начале списка, что удобно для автодополнения.
Awesomplete не всегда автоматически реагирует на изменения массива,
поэтому требуется явное обновление list.
function updateAwesomplete(list) {
awesomplete.list = list;
}
И интеграция с сохранением:
function saveToStorage(value) {
const key = "awesomplete-data";
const stored = localStorage.getItem(key);
let list = stored ? JSON.parse(stored) : [];
if (!list.includes(value)) {
list.unshift(value);
}
if (list.length > 20) {
list = list.slice(0, 20);
}
localStorage.setItem(key, JSON.stringify(list));
updateAwesomplete(list);
}
Таким образом достигается синхронизация между UI-компонентом и локальным состоянием.
В некоторых сценариях требуется сброс истории подсказок, например при смене пользователя или очистке данных приложения.
function clearAwesompleteStorage() {
localStorage.removeItem("awesomplete-data");
awesomplete.list = [];
}
После удаления данных важно также очистить состояние Awesomplete, иначе устаревшие подсказки останутся в интерфейсе.
При использовании одного поля ввода в разных режимах (например, поиск товаров и поиск документов) необходимо разделять ключи хранения.
function getStorageKey(context) {
return `awesomplete-${context}`;
}
Использование:
function saveToStorage(value, context) {
const key = getStorageKey(context);
const stored = localStorage.getItem(key);
let list = stored ? JSON.parse(stored) : [];
if (!list.includes(value)) {
list.unshift(value);
}
localStorage.setItem(key, JSON.stringify(list));
}
Это предотвращает смешивание данных разных сценариев.
Awesomplete поддерживает не только строки, но и объекты вида
{ label, value }. При использовании
localStorage требуется учитывать сериализацию.
const item = { label: "JavaScript", value: "js" };
localStorage.setItem("awesomplete-data", JSON.stringify([item]));
При восстановлении:
const stored = JSON.parse(localStorage.getItem("awesomplete-data"));
const awesomplete = new Awesomplete(input, {
list: stored
});
В этом случае важно сохранять стабильную структуру объектов, иначе подсказки могут отображаться некорректно.
Для повышения качества автодополнения часто требуется фильтрация вводимых значений.
function normalize(value) {
return value.trim().toLowerCase();
}
Интеграция:
function saveToStorage(value) {
const key = "awesomplete-data";
const normalized = normalize(value);
const stored = localStorage.getItem(key);
let list = stored ? JSON.parse(stored) : [];
const normalizedList = list.map(normalize);
if (!normalizedList.includes(normalized)) {
list.unshift(value);
}
localStorage.setItem(key, JSON.stringify(list));
}
Таким образом устраняется дублирование, вызванное различиями в регистре и пробелах.
При больших объёмах данных целесообразно откладывать чтение
localStorage до момента фокусировки на поле ввода.
let awesomplete;
input.addEventListener("focus", function () {
if (!awesomplete) {
const stored = localStorage.getItem("awesomplete-data");
const list = stored ? JSON.parse(stored) : [];
awesomplete = new Awesomplete(input, {
list: list
});
}
});
Такой подход снижает нагрузку при загрузке страницы и переносит инициализацию на момент реального использования.
localStorage хранит данные в виде строк, поэтому
возможны ошибки при парсинге.
function safeParse(data) {
try {
return JSON.parse(data);
} catch (e) {
return [];
}
}
Использование:
const stored = safeParse(localStorage.getItem("awesomplete-data"));
Это предотвращает поломку логики автодополнения при повреждённых данных.
При развитии приложения структура хранимых данных может меняться. Для этого вводится версия хранилища.
const STORAGE_VERSION = "v1";
function getKey(context) {
return `awesomplete-${context}-${STORAGE_VERSION}`;
}
Это позволяет безопасно мигрировать данные без конфликтов между версиями формата.
При большом количестве записей можно уменьшить объём хранения за счёт упрощения структуры.
const list = ["javascript", "python", "go"];
localStorage.setItem("awesomplete-data", list.join("|"));
Восстановление:
const stored = localStorage.getItem("awesomplete-data");
const list = stored ? stored.split("|") : [];
Такой формат уменьшает накладные расходы JSON, но требует строгого контроля символов-разделителей.
localStorage можно использовать не только как хранилище истории, но и как простую систему веса.
function saveToStorage(value) {
const key = "awesomplete-data";
const stored = localStorage.getItem(key);
let map = stored ? JSON.parse(stored) : {};
map[value] = (map[value] || 0) + 1;
localStorage.setItem(key, JSON.stringify(map));
}
Формирование списка для Awesomplete:
function buildList(map) {
return Object.entries(map)
.sort((a, b) => b[1] - a[1])
.map(entry => entry[0]);
}
Это позволяет реализовать адаптивное автодополнение, где чаще используемые элементы поднимаются выше.
При длительном использовании данных необходимо периодически удалять редко используемые элементы.
function prune(map, threshold) {
const result = {};
for (const key in map) {
if (map[key] >= threshold) {
result[key] = map[key];
}
}
return result;
}
Такая стратегия предотвращает деградацию качества подсказок и
контролирует рост объёма данных в localStorage.