Civil &: строительная инженерия
Создание менеджера закладок Javascript с локальной устойчивостью к хранению
Table of Contents
Понимание основ
Создание менеджера закладок с JavaScript и API Web Storage - отличный проект для освоения фундаментальных концепций интерфейса. По своей сути приложение должно обрабатывать три основные операции: , , , , и , удалить - классический шаблон CRUD, минус обновления на данный момент. Данные живут в локальном хранилище браузера , позволяя закладкам сохраняться в течение сессий без сервера.
Прежде чем писать одну строку кода, укрепите свое понимание следующих столпов:
- DOM API: Вы будете запрашивать элементы, слушать события и манипулировать деревом документов, чтобы динамически отображать закладки.
- localStorage: Этот хранилище ключевых значений сохраняет данные даже после закрытия браузера. Он поддерживает только строки, поэтому объекты должны быть сериализованы с и десериализированы с .
- Программирование на основе событий: Формы испускают события; удаляют кнопки, зажигающие события. Освоение не подлежит обсуждению.
- Методы массива: , и помогут эффективно отображать и манипулировать списком закладок.
Создание Core Bookmark Manager
HTML структура
Начните с минимального семантического HTML-скелета. Форма собирает имя закладки и URL; неупорядоченный список отображает сохраненные закладки.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bookmark Manager</title>
</head>
<body>
<h1>My Bookmarks</h1>
<form id="bookmarkForm">
<label for="name">Name</label>
<input type="text" id="name" required />
<label for="url">URL</label>
<input type="url" id="url" required />
<button type="submit">Add Bookmark</button>
</form>
<ul id="bookmarkList"></ul>
<script src="app.js" defer></script>
</body>
</html>
Обратите внимание на атрибут на теге сценария — он гарантирует, что DOM полностью разбирается перед запуском сценария, устраняя необходимость в обертке в современных настройках.
Стилизованный для удобства использования (необязательно, но рекомендуется)
Хотя CSS не является фокусом, чистый интерфейс улучшает пользовательский опыт. Добавьте простой таблицу стилей, чтобы разобрать форму, придать кнопкам последовательный вид и стиль закладок с эффектами наведения. Минимальный встроенный стиль также может быть введен через JavaScript, но для удобства обслуживания предпочтительнее отдельный .
<!-- inside <head> -->
<link rel="stylesheet" href="style.css" />
В используйте флексбокс для макета формы, максимальной ширины для контейнера и четкой визуальной обратной связи для кнопок удаления, чтобы предотвратить случайные щелчки.
Логика JavaScript – сердце приложения
Вся настойчивость и интерактивность живут в . Следующие разделы разбивают каждую функцию.
Инициализация данных
Нам нужна центральная переменная, держащая текущий список закладок. Она должна быть инициализирована из или вернуться к пустому массиву.
let bookmarks = [];
function loadBookmarks() {
const stored = localStorage.getItem('bookmarks');
if (stored) {
bookmarks = JSON.parse(stored);
} else {
bookmarks = [];
}
}
function saveBookmarks() {
localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
}
loadBookmarks();
Функция называется каждый раз, когда массив изменяется — после добавления, редактирования или удаления закладки. Это гарантирует, что хранилище всегда синхронизируется с массивом в памяти.
Отображение закладок
Передача списка закладок означает повторение над массивом и создание элементов списка с якорной меткой и кнопкой удаления.
function renderBookmarks() {
const list = document.getElementById('bookmarkList');
list.innerHTML = ''; // clear existing entries
bookmarks.forEach(function(bookmark, index) {
const li = document.createElement('li');
li.dataset.index = index;
const link = document.createElement('a');
link.href = bookmark.url;
link.textContent = bookmark.name;
link.target = '_blank';
link.rel = 'noopener noreferrer';
const deleteBtn = document.createElement('button');
deleteBtn.textContent = 'Delete';
deleteBtn.addEventListener('click', function() {
deleteBookmark(index);
});
li.appendChild(link);
li.appendChild(deleteBtn);
list.appendChild(li);
});
}
Использование вместо внутреннего HTML позволяет избежать уязвимостей XSS, когда имена закладок содержат HTML. Кнопка удаления использует закрытие для захвата индекса закладки.
Добавить закладку
Слушайте событие формы , предотвращайте перезагрузку страницы по умолчанию, создайте объект закладки, подтолкните его к массиву, сохраняйте и перезадавайте.
document.getElementById('bookmarkForm').addEventListener('submit', function(e) {
e.preventDefault();
const nameInput = document.getElementById('name');
const urlInput = document.getElementById('url');
const newBookmark = {
name: nameInput.value.trim(),
url: urlInput.value.trim()
};
// Basic validation: ensure URL starts with http/https
if (!newBookmark.url.startsWith('http://') && !newBookmark.url.startsWith('https://')) {
newBookmark.url = 'https://' + newBookmark.url;
}
bookmarks.push(newBookmark);
saveBookmarks();
renderBookmarks();
// Reset form
nameInput.value = '';
urlInput.value = '';
nameInput.focus();
});
Для производства вы можете проверить формат URL, используя конструктор или регекс.
Удаление закладки
Удаление удаляет элемент в данном индексе и обновляет хранилище и DOM.
function deleteBookmark(index) {
bookmarks.splice(index, 1);
saveBookmarks();
renderBookmarks();
}
Если вы предпочитаете неизменяемость, вы можете использовать и переназначить , но для небольшого проекта, подобного этому, является ясным и исполнителем.
Усовершенствование приложения
После того, как базовый CRUD работает, рассмотрите эти улучшения, чтобы превратить прототип в надежный инструмент.
Редактирование закладок
Заменить статическое имя/ссылку режимом встроенного редактирования. При нажатии пользователем кнопки редактирования поменять якорный тег на поля ввода, предварительно заполненные текущими значениями. На сохранение, обновление массива и сохранение.
Подсказка по реализации: добавьте функцию , которая создает редактируемые входные данные. Используйте делегирование событий в списке для обработки сохранения правок без прикрепления нескольких слушателей.
Категоризация с тегами
Добавьте дополнительное свойство к каждому объекту закладки (например, ). Затем расширьте пользовательский интерфейс с помощью входного фильтра, который скрывает элементы списка, теги которых не совпадают. Вы можете хранить теги в виде выделенной запятой строки внутри формы и разделить их на массив.
Импорт и экспорт
Разрешить пользователям резервное копирование или передачу закладок. Используйте или загрузку файла. Экспорт сериализует в строку JSON и запускает загрузку через и . Импорт читает JSON и сливается с существующими закладками.
function exportBookmarks() {
const data = JSON.stringify(bookmarks, null, 2);
const blob = new Blob([data], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'bookmarks.json';
a.click();
URL.revokeObjectURL(url);
}
Поиск и фильтр
Добавьте ввод выше списка закладок. На каждом событии отфильтровывайте массив по имени (или URL) и называйте вариант , который отображает только совпадения. Чтобы избежать потери первоначального списка, храните отфильтрованную копию или используйте вычисленный параметр.
Тестирование и совместимость браузера
LocalStorage поддерживается во всех современных браузерах, но более старые версии Internet Explorer (IE 8+) имели другой API. Если вам необходимо поддерживать устаревшие среды, тестируйте с полифиллами или возвращайтесь к файлам cookie. Сегодняшние Chrome, Firefox, Safari, Edge (как Chromium, так и legacy) обрабатывают и без проблем.
При тестировании проверьте:
- Данные выживают после обновления страницы и перезапуска браузера.
- Удаление закладки обновляет как пользовательский интерфейс, так и хранилище.
- Специальные символы в закладочных именах (цитатах, амперсандах) отображаются правильно.
- URL с и без являются нормализованными.
Используйте инструменты разработчика > Application > Storage > Local Storage для ручного контроля сохраненных данных.
Для автоматизированного тестирования рассмотрите возможность использования Cypress или Playwright для имитации рабочих процессов пользователя — заполните форму, добавьте, удалите, перезагрузите — и утверждайте, что список сохраняется.
Заключение
Этот проект демонстрирует, как несколько десятков строк ванильного JavaScript могут создать полностью функциональное, постоянное веб-приложение. Вы научились использовать API localStorage для сохранения данных, делегирование событий для эффективных обновлений пользовательского интерфейса и CRUD-операции без бэкэнда. Применяемый вами шаблон — инициализация состояния из хранилища, мутация состояния через функции и повторное воспроизведение DOM — является основой многих современных интерфейсных фреймворков, таких как React или Vue.
Чтобы углубить свое понимание, изучите документацию MDN по локальному хранению и прочитайте о обработке событий в DOM . Для более продвинутого управления состоянием, взгляните на IndexedDB для больших наборов данных или сервисных работников для офлайн-первого опыта. С этими строительными блоками вы можете теперь расширить своего менеджера закладок в полноценную личную базу знаний.