Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. HTML & CSS

Реализация возможности добавления стикеров для заметок при помощи веб-хранилища.

by
Difficulty:IntermediateLength:LongLanguages:
This post is part of a series called HTML5 and You.
Getting Offline Access with HTML5 Application
HTML5 Apps: What, Why, and How

Russian (Pусский) translation by AlexBioJS (you can also view the original English article)

(* локальное хранилище, HTML5-хранилище, DOM-хранилище; встроенная возможность хранения данных на стороне клиента (объем данных значительно больше того, что предоставляется куки-файлами). Здесь и далее примеч. пер.). Локальное хранилище HTML5 – что-то вроде куки на стероидах; его чрезвычайно легко использовать, и в то же время оно представляет из себя настолько мощную функциональную возможность. В этом руководстве я покажу вам, как реализовать возможность добавления «стикеров для заметок», за счет которой у ваших пользователей появляется возможность делать постоянные заметки при просмотре вашего сайта.


Шаг 1: HTML

Из-за динамической природы этого проекта нам особо нечего программировать, что касается обычной старой семантической разметки. Мы просто будем симулировать веб-страницу за счет сведения воедино кое-какого контента-наполнителя.

Здесь стоит обратить внимание на несколько важных моментов. Мы добавляем два CSS-файла: первый, который мы назвали default.css используется для добавления простого стилевое оформление для страницы. Далее идет специальный CSS-файл для добавления стилевого оформления для наших стикеров для заметок под названием stickies.css, и как вы видите он располагается в папке “stickies”. В нижней части документа мы добавляем четыре скрипта:

  • jQuery с CDN (* content delivery network – сеть доставки (распространения) контента) Google
  • JQuery UI с CDN Google
  • JSON2 с сайта Дугласа Крокфорда
  • Наш собственный stickies.js, который располагается в папке “stickies”

Далее идет пустой элемент script, который мы будем использовать для приведения кода в действие.

И на этом все с HTML!


Шаг 2: CSS

Содержимое default.css чрезвычайно просто:

И все; теперь осталось взглянуть на CSS-код stickies.css ... однако у нас еще нет для него HTML-разметки. Так что давайте приступим к написанию кое-какого кода JavaScript, и после этого мы разберемся с CSS-кодом для записок-наклеек.


Шаг 3: JavaScript

Ниже приведен каркас нашего JavaScript-приложения:

Мы используем здесь несколько интересных приемов. Первый – функция-выражение немедленного вызова: может показаться, что мы присваиваем функцию переменной STICKIES, однако если вы приглядитесь к концу функции, то увидите, что мы ее тут же и запускаем. В качестве намека для напоминания нам, что это не обычная функция, мы оборачиваем всю функцию в круглые скобки. Так что STICKIES – не функция, а возвращенное той функцией значение, являющееся объектом в нашем случае.

Это подводит нас к следующему приему – замыкание (* комбинация функции и лексического окружения, в котором она была объявлена; функция + внешние переменные). Обратите внимание на то, что из шести созданных нами функций только две предоставляются пользователю (в действительности лишь одна необходима в случае нашего приложения; если бы мы хотели добавить возможность создания записей в ваш веб-сайт, то могли бы предоставить и функции createSticky и deleteSticky). Несмотря на то что функция-выражение немедленного вызова прекращает выполняться еще перед тем, как мы даже воспользуемся этими методами, у нас будет возможность воспользоваться другими функциями, которые мы определили.

Хорошо, давайте перейдем к содержимому этих функций.


initStickies

Мы начнем с рассмотрения функции initStickies:

Она довольно проста. Мы будем использовать jQuery для создания элементов довольно часто, и мы используем кое-какой специальный синтаксис в версии 1.4: передача литерала объекта с настройками для элемента в качестве второго параметра в функцию jQuery. Здесь мы создаем кнопку для создания новой заметки. То есть нам нужен новый элемент div; мы задаем в качестве значения text ”+” и добавляем класс “add-sticky”; затем мы задаем обработчик для события click, чтобы вызвать метод createSticky (важно, чтобы createSticky вызывался из функции, а не непосредственно в качестве обработчика события click; это так, поскольку createSticky может принимать единственный параметр, и нам не нужно, чтобы это был объект события). Наконец, мы добавляем этот div в начале элемента body. Мы завершаем тем, что задаем в качестве значения initStickies null; да, мы по сути избавляемся от функции, которая выполняется. За счет этого гарантируется, что эта функция будет выполняться только раз; мы не хотели бы, чтобы пользователь нашего API по неосторожности добавил множество кнопок “add note” на страницу.

openStickies

Давайте перейдем к следующему методу – openStickies:

Мы начинаем с запуска функции initStickies ... но для чего используем тот необычный синтаксис? Что ж, вы, наверное, знакомы с оператором && – булев оператор AND. Вы бы обычно использовали его в операторе if, чтобы проверить, выполняются ли несколько условий. При помощи него собственно выполняется следующее: вычисляется значение первого выражения, и если им является true, то далее вычисляется значение второго выражения. В нашем случае, если в качестве значения initStickies еще не было задано null, то функция будет выполнена. За счет этого мы избегаем появления ошибки, которая возникла бы при попытке запуска переменной со значением null в качестве функции.

Далее мы перебираем каждый элемент в localStorage. Ниже описано, что происходит в том цикле for-loop (изнутри кнаружи):

  • localStorage.key() – замечательная функция, которая возвращает имя ключа значения localStorage; она принимает число в качестве параметра. Это замечательный способ перебора всех элементов localStorage.
  • После получения ключа хранимого элемента мы можем передать его localStorage.getItem() для получения его значения.
  • Затем мы передаем это значение в JSON.parse(); этот метод поставляется в составе библиотеки Крокфорда. Поскольку мы храним несколько значений для каждой заметки, то используем JSON.stringify() на другой стороне (* метод saveSticky) для превращения объекта в JSON-строку, которую сохраняем. Здесь мы превращаем ее из строки обратно в объект.
  • Наконец, мы передаем этот объект в метод createSticky(), при помощи которого он превращается обратно в стикер для заметок.

createSticky

Теперь давайте взглянем на тот метод createSticky.

Да, он длинный, однако с ним будет не слишком трудно разобраться. Для начала обратите внимание, что эта функция принимает объект data; как мы только что видели в функции openStickies, мы передаем сохраненные данные этой функции. Однако если мы не передаем никаких данных (то есть мы создаем совершенно новую заметку), то мы создадим объект заметки по умолчанию. Поскольку все заметки должны быть созданы в какой-то момент, для всех заметок изначально будут заданы эти настройки. Обратите внимание, что в качестве id заметки мы используем +new Date(); при помощи того добавленного в начале одинарного оператора плюс дата, возвращенная new Date(), превращается в число, так что в результате вычисления этого выражения возвращается число, представляющее из себя количество миллисекунд, прошедших с 1 января, 1970 года. Очевидно, что это число будет постоянно изменяться, так что это замечательный способ однозначно идентифицировать каждую заметку.

Остальная часть функции представляет из себя длинную строку сцепленных методов jQuery. Перед тем как приступить к их разбору, обратите внимание, что мы возвращаем результат. Если бы мы предоставили этот метод разработчикам при помощи нашего микро-API, то он бы возвратил ссылку на элемент div стикера для заметок.

Что ж, ниже перечислено, что происходит:

  • Для начала мы создаем div, который является каркасом нашего стикера для заметок. За счет того полезного синтаксиса jQuery 1.4 мы задаем для него класс “sticky” и id из объекта data.

  • Затем мы добавляем в начале этого элемента div другой; для него задается класс “sticky-header”. Затем в div.sticky-header добавляются два элемента span. Для первого, span.sticky-status, добавляется обработчик события click, за счет которого вызывается функция saveSticky. Однако это собственно скрытая возможность: при помощи этого span будет отображаться статус заметки: saved или unsaved (* не сохранено). Будет несколько способов сохранения данных заметки в localStorage; вероятно, что пользователь будет думать, что за счет нажатия ‘unsaved’ заметка будет сохранена, так что мы предоставим им эту функциональную возможность. Второй элемент span, span.close-sticky, будет являться кнопкой delete: при нажатии ее пользователем мы удалим заметку из localStorage при помощи метода deleteSticky. Мы передаем в этот метод id заметки.

  • Далее мы добавляем еще один div к главному div.sticky; обратите внимание, что мы задали в качестве значения свойства html data.text; при сохранении текста заметки мы используем метод html() jQuery, поскольку при использовании text() убираются переносы строк. Также мы добавляем contentEditable:true для этого div, поскольку это контент заметки. Поэтому для него также задается класс sticky-content. Наконец, при нажатии клавиши, когда пользователь изменяет его контент, нам нужно пометить этот элемент div как unsaved, так что мы вызовем соответственную функцию (которую скоро реализуем).

  • Далее мы используем возможность перетаскивания jQuery UI, чтобы наш стикер для заметок можно было перемещать. В нашем объекте, который передаем в качестве параметра, мы используем свойство handle, чтобы наши заметки можно было перемещать только при помощи верхней панели. Свойство stack – селектор для перетаскиваемых элементов, используемый, чтобы они могли «разместиться поверх друг друга»; за счет указания его значения перетаскиваемая в данный момент заметка всегда располагается сверху. Наконец, когда заметка начинает перемещаться, нам необходимо пометить ее как “unsaved” (поскольку нам нужно сохранить также и ее координаты), и по окончании перетаскивания мы сохраним эту заметку.

  • Далее мы задаем некоторые стилевые правила для нашего div.sticky; мы устанавливаем для него абсолютное позиционирование и затем задаем в качестве значений его свойств top и left те, что содержатся в объекте data. За счет этого расположение и контент заметки останутся на прежнем месте, когда мы обновим страницу.

  • Наконец, мы зададим обработчик событий для случаев, когда мы перемещаем фокус за пределы заметки (по сути нажимаем за пределами ее после нажатия внутри нее): нам необходимо сохранить заметку. Наконец, мы добавим ее в конце body. Вам для справки: ниже приведена HTML-структура, которая у нас должна получиться:

И это была наша функция createSticky.

deleteSticky

Далее идет функция deleteSticky; она очень проста:

Как вы помните, функция deleteSticky принимает id заметки в качестве своего параметра. localStorage.removeItem() – ключевой метод здесь: мы передаем ему ключ сохраненного локально значения, чтобы удалить эту пару ключ-значение (Обратите внимание, что когда мы сохраняем данные заметки, то добавляем в начале id “sticky-”). Затем мы находим элемент с соответствующим id, делаем так, чтобы он постепенно исчез, и удаляем его. Заметка удалена!

saveSticky

Предпоследний метод (saveSticky), вероятно, наиболее важный в этом руководстве: это клей, за счет которого здесь все работает.

Первая строка – выполнение некоторого приведения (* ссылки к div.sticky): имеется три разных элемента, из которых мы можем вызвать эту функцию. Для начала мы заменим this на that за счет возможностей jQuery; затем, если у элемента имеется либо класс “sticky-status”, либо “sticky-content”, то мы получим его родительский элемент, div.sticky; если у него нет никакого из этих классов, то элементом является сам div.sticky, так что мы просто воспользуемся им.

Затем нам необходимо получить значения, которые хотим сохранить. Как вы видите, мы получаем id, отступы сверху и слева, и HTML-код дочернего элемента с классом .sticky-content; помните, что мы используем html() вместо text(), поскольку хотим сохранить переносы строк. Затем мы используем localStorage.setItem для сохранения данных. Помните, что этот метод принимает два параметра: ключ и значение, которые необходимо сохранить. Поскольку localStorage сохраняет только строки, мы используем JSON.stringify() для преобразования объекта в строку.

Наконец, мы изменяем статус заметки на “saved.”

markUnsaved

У нас имеется одна последняя функция, которая является просто вспомогательной функцией:

Опять-таки, нам нужно начать с приведения ссылки к div.sticky; после этого мы можем просто получить элемент span и указать в качестве его текста “unsaved.”

Хотите – верьте, хотите – нет, это все был код JavaScript.


Шаг 4: Доработанный CSS-код

Теперь, когда мы знаем, как выглядит разметка для нашей заметки, мы можем добавить для нее стилевое оформление.  Оно довольно просто; однако просмотрите код, а я приведу несколько комментариев в конце:

Здесь имеется несколько моментов, на которые следует обратить внимание:

  • Некоторые браузера добавляют контур вокруг элементов при помощи contenteditable=true, когда вы редактируете контент. Нам это не нужно, поэтому мы избавляемся от него за счет  добавления правила :focus.
  • Кнопка “Add Sticky” располагается в верхнем левом углу; она отчасти напоминает по внешнему виду “Add Dashboard Widget” в Mac OS X.
  • Мы используем свойства CSS3 border-radius и box-shadow (и их соответственные варианты с префиксами вендоров).
  • Также мы используем rgba() для задания цветов теней. Этот метод принимает четыре параметра: красный, зеленый и синий цвета, а также значение alpha (* в компьютерной графике - четвёртый компонент цвета, используемый для контроля смешивания цветов с фоном или нижележащим объектом. При этом его значение 1,0 означает полную непрозрачность, а 0,0 - полную прозрачность).

В остальном это просто ваш стандартный CSS-код. Ниже показано, как должна выглядеть заметка со стилевым оформлением:

Note

Шаг 5: Запуск кода для реализации стикеров

Теперь, когда у нас имеется наш API, пришло время его запустить; мы можем это сделать из дополнительного пустого элемента script в нашем файле index.html:

Заключение: Конечный результат

Что ж, на этом все! Ниже показан конечный результат в действии:

Это все, что у меня было для вас на сегодня; как вы планируете использовать HTML5-хранилище для оживления ваших веб-проектов? Дайте мне знать об этом ниже в разделе для добавления комментариев!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.