Створення «клейких» нотаток, використовують локальну память

307

Від автора: Локальна пам’ять HTML5 – це cookies на стероїдах; її неймовірно легко використовувати, і в той же час вона дуже потужна. У цьому уроці я покажу вам, як створити функціональні «sticky notes» («клейкі нотатки»), які дозволять користувачам робити постійно відображаються записи під час перегляду вашого сайту.

Перед тим, як ми приступимо до практичних кроків, я Вам рекомендую переглянути демо-результат роботи.

Також завантажте вихідні коди собі на комп’ютер!

Створення «клейких» нотаток, використовують локальну память

Крок 1: HTML

Оскільки цей проект має динамічну природу, нам не потрібно що-небудь кодувати в стилі звичайної семантичної розмітки. Ми просто змоделюємо веб-сторінку, склавши разом трохи вмісту:

HTML 5 complete

Sample Article Title

Copyright 2010 Andrew Burgess

Тут потрібно відзначити деякі важливі моменти: ми включаємо два файлу CSS: перший – простий дизайн сторінки, названий нами default.css. Потім, у нас є спеціальний файл CSS стилів, що стосуються наших «клейких нотаток»; він називається stickies.css, і, як можна бачити, що знаходиться в папці «stickies». Внизу ми включаємо чотири скрипта:

jQuery, Google CDN (мережі доставки контенту)

JQuery UI, з CDN Google

JSON2, Douglas Crockford

Наш власний stickies.js, що знаходиться в каталозі «stickies»

Далі, у нас є порожній тег скрипта, який ми використовуємо трохи пізніше для запуску двигуна.

На цьому з HTML-все!

Крок 2: CSS

Вміст файлу default.css неймовірно просте:

body {
margin:0;
padding:0;
background:#ccc;
font:14px/1.5 “Helvetica Neue”, Helvetica, Arial, sans-serif;
}
article, footer, header { display: block; }
article {
width:880px;
background:#fff;
margin:auto;
padding:40px;
}
article header {
color:#474747;
border-bottom:1px solid #474747
}
article footer {
font-size:90%;
color:#ccc;
}

От і все; тепер потрібно подбати про CSS файлу stickies.css… але у нас ще немає розмітки. Так що давайте візьмемося за JavaScript, а коли закінчимо, подивимося CSS для клейких нотаток.

Крок 3: JavaScript

Це основа нашої програми JavaScript:

var STICKIES = (function () {
var initStickies = function () {},
openStickies = function () {},
createSticky = function (data) {},
deleteSticky = function (id) {},
saveSticky = function () {},
markUnsaved = function () {};
return {
open : openStickies,
init : initStickies
};
}());

Тут у нас використовуються деякі цікаві методики. Перша – це самовызываемая функція: виглядає це таким чином, начебто ми призначаємо функцію змінної STICKIES, але якщо подивитися уважно на кінець функції, ви побачите, що ми запускаємо її відразу ж. В якості підказки — щоб все нагадувало нам про те, що це незвичайна функція — ми обертаємо її цілком у круглі дужки. Таким чином, STICKIES – не функція, це обчислене значення функції, яка в даному випадку є об’єктом.

Це веде нас до наступного прийому: замикання (closure). Зверніть увагу, що з шести створюваних нами функцій всього дві використовуються користувачем (в дійсності для запланованого використання необхідна тільки одна; якщо б ми хотіли забезпечити створення заміток у своєму веб-сайті, ми могли б показати createSticky і deleteSticky). Хоча самовызываемая функція закінчує своє виконання до використання цих методів, ми зможемо використовувати інші задані нами функції.

Так, давайте перейдемо до їх змісту.

initStickies

Почнемо з розгляду функції initStickies:

var initStickies = function initStickies() {
$(“

“, {
text : “+”,
“class” : “add-sticky”,
click : function () { createSticky(); }
}).prependTo(document.body);
initStickies = null;
},

Це досить просто. Ми використовуємо jQuery для створення елементів, і користуємося спеціальним синтаксисом версії 1.4: тобто передаємо об’єктну константу специфікаціями елемента як другого параметра функції jQuery. Ось, ми робимо кнопку створення нової нотатки. Це означає, що нам потрібен новий div; ми встановлюємо текст на «+» і присвоюємо йому клас «add-sticky»; потім встановлюємо оброблювач натискання на виклик методу createSticky (важливо викликати createSticky з функції, а не змушувати обробник клацання звертатися безпосередньо до createSticky; це тому, що createSticky може приймати одиничний параметр, а нам не потрібно, щоб він був багатим на події об’єктом). Нарешті, ми вставляємо цей div у body. Закінчимо установкою initStickies у null; та, по суті, ми позбавляємося від запуску функції. Таким чином переконаємося, що ця функція буде запущено всього один раз; нам не потрібно, щоб користувач нашого API (додатки) за неуважність додав до сторінки безліч кнопок “add note” (“додати примітку”).

openStickies

Давайте перейдемо до наступного методу — openStickies:

openStickies = function openStickies() {
initStickies && initStickies();
for (var i = 0; i < localStorage.length; i++) {
createSticky(JSON.parse(localStorage.getItem(localStorage.key(i))));
}
},

Почнемо з запуску initStickies … але що відбувається в цьому химерному синтаксисі? Ну, ви, напевно, знайомі з оператором &&: логічним оператором «і». Зазвичай ним користуються, щоб перевірити множинні умови в if-операторі. Ось що насправді він робить: обчислює перший вираз, і якщо воно виявляється вірним (true), продовжує обчислення другого виразу. У цьому випадку, якщо initStickies ще не був встановлений на нуль, ми запустимо функцію. Таким чином, ми уникнемо помилки, яка відбудеться, якщо спробувати запустити нульову змінну функцію.

Далі перебираємо по черзі кожен пункт в localStorage. Ось що ми робимо в цьому циклі з параметром:

localStorage.key() – відмінна функція, що повертає назву ключа значення localStorage; вона приймає як параметр число. Прекрасний спосіб переглянути по порядку (у вигляді циклу) всі пункти в localStorage.

Як тільки у нас з’являється ключ зберігається пункту, ми можемо передати його в localStorage.getItem() для отримання його значення.

Потім передаємо це значення в JSON.parse(); його ми отримуємо з бібліотеки Crockford. Так як ми зберігаємо за кілька значень для кожної замітки, з іншого кінця користуємося JSON.stringify() для перетворення об’єкту в рядок JSON, яку зберігаємо. Ось тут ми перетворимо її з рядка назад в об’єкт.

Нарешті, передаємо об’єкт в createSticky(), який перетворює його назад в клейку замітку.

createSticky

Тепер розглянемо метод createSticky.

createSticky = function createSticky(data) {
data = data || { id : +new Date(), top : “40px”, left : “40px”, text : “Note Here” }
return $(“

“, {
“class” : “sticky”,
‘id’ : data.id
})
.prepend($(“

“, { “class” : “sticky-header”} )
.append($(““, {
“class” : “status-sticky”,
click : saveSticky
}))
.append($(““, {
“class” : “close-sticky”,
text : “trash”,
click : function () { deleteSticky($(this).parents(“.sticky”).attr(“id”)); }
}))
)
.append($(“

“, {
html : data.text,
contentEditable : true,
“class” : “sticky-content”,
keypress : markUnsaved
}))
.draggable({
handle : “div.sticky-header”,
stack : “.sticky”,
start : markUnsaved,
stop : saveSticky
})
.css({
position: “absolute”,
“top” : data.top,
“left”: data.left
})
.focusout(saveSticky)
.appendTo(document.body);
},

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

Інша функція – це довга рядок збудованих ланцюжком методів jQuery. Перед тим, як зайнятися ними, зверніть увагу, що ми повертаємо результат. Якщо б ми публікували цей метод розробникам через API, що використовує наше микроприложение, вони б згадали посилання на елемент div клейкою нотатки.

Отже, ось що відбувається:

По-перше, ми створюємо div, є контейнером для нашої замітки. За допомогою корисного синтаксису jQuery 1.4 присвоюємо йому клас «sticky» і id об’єкта даних.

Потім вставляємо туди ще один div; він отримує клас «sticky-header». Div.sticky-header потім отримує два прикріплених до себе діапазону. Перший, span.sticky-status, отримує обробник клацання, викликає функцію saveSticky. Проте насправді це приховане властивість: цей діапазон покаже статус примітки: збережена або не збережена. Замітка буде зберігати свої дані в localStorage кількома способами; можливо, користувач визнає, що збереже замітку натискання ‘unsaved’, так що забезпечимо його і цією функціональністю. Другий діапазон, span.close-sticky, стане клавішею видалення: коли користувач натисне її, ми видалимо замітку з localStorage за допомогою методу deleteSticky. Передаємо цього методу id нотатки.

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

Тепер скористаємося властивістю перетягування jQuery UI, щоб наша клейка замітка могла переміщатися. В об’єктному полі використовуємо властивість handle, щоб нотатки могли пересуватися смуги заголовків. Властивість stack – це селектор для елементів, що мають можливість пересуватися, щоб вони прагнули складатися в одне місце (stack); після його установки поточна переміщувана замітка обов’язково виявиться зверху. Нарешті, на початку перетягування замітки нам потрібно позначити її як незбережену («unsaved»), тому що потрібно зберегти її координати, а після закінчення перетягування ми збережемо цей стікер.

Далі визначаємо стилі для свого div.sticky; встановлюємо позиціонування за абсолютними координатами, а потім встановлюємо властивості верху і лівого краю в відповідності з об’єктом даних. Таким чином, при оновленні сторінки замітка буде зберігати як свою позицію, так і вміст.

Нарешті встановимо обробник події focusout на стікері (по суті, клацаємо поза його після клацання по ньому): нам потрібно зберегти вміст стікера. Зрештою, ми прикріпимо його до тегу body. Для довідки, ось структура html, яка повинна була у нас вийде:


trash
Note Here

Ось вона, функція createSticky.

deleteSticky

Тепер у нас функція deleteSticky, вона дійсно проста:

deleteSticky = function deleteSticky(id) {
localStorage.removeItem(“sticky-” + id);
$(“#” + id).fadeOut(200, function () { $(this).remove(); });
},

Як ви пам’ятаєте, функція deleteSticky приймає id замітки як свій параметр. localStorage.removeItem() – актуальний метод: ми передаємо ключ до локально зберігається значення для видалення цієї пари ключ-значення (зауважте, що при зберіганні даних примітки ми вставляємо в id «sticky-»). Потім знаходимо елемент з даними id, змушуємо його згаснути і видаляємо. Замітка видалено!

saveSticky

Передостанній на сьогодні, можливо, найважливіший метод:

saveSticky = function saveSticky() {
var that = $(this), sticky = (that.hasClass(“sticky-status”) || that.hasClass(“sticky-content”)) ? that.parents(‘div.sticky’): that,
obj = {
id : sticky.attr(“id”),
top : sticky.css(“top”),
left: sticky.css(“left”),
text: sticky.children(“.sticky-content”).html()
}
localStorage.setItem(“sticky-” + obj.id JSON.stringify(obj));
sticky.find(“.sticky-status”).text(“saved”);
},

Перший рядок – це ідентифікація: функцію можна викликати з трьох різних елементів. По-перше, ми «jQuery-фицируем» this у that; потім, якщо у елемента є класи «sticky-status» або «sticky-content», отримаємо батьківський div.sticky; якщо немає ні одного з цих класів, тоді це і є сам div.sticky, так що просто використовуємо його.

Далі потрібно отримати значення, які потрібно зберігати. Як можна бачити, ми отримуємо id, зміщений зверху і зліва, і html дочірнього .sticky-content; пам’ятаєте, ми користуємося html() замість text(), тому що потрібно підтримувати розриви рядків. Тепер ми використовуємо localStorage.setItem для зберігання даних. Запам’ятайте, що він приймає на зберігання два параметра: ключ і значення. Так як localStorage зберігає тільки рядки, ми користуємося JSON.stringify() для перетворення об’єкту в рядок.

На закінчення змінюємо статус стікера на «saved.»

markUnsaved

У нас залишилася остання функція, допоміжна:

markUnsaved = function markUnsaved() {
var that = $(this), sticky = that.hasClass(“sticky-content”) ? that.parents(“div.sticky”) : that;
sticky.find(“.sticky-status”).text(“unsaved”);
}

Нам знову потрібно почати з дозволу посилання на div.sticky; зробивши це один раз, можна просто відшукати діапазон статусу і встановити текст «unsaved».

Вірите чи ні, але з JavaScript ми закінчили.

Крок 4: перероблений CSS

Тепер, коли ми знаємо, яка розмітка клейкою замітки, можна додати в неї стилів. Це досить просто; але ретельно вивчіть цей процес, а я в кінці трохи прокоментую його:

:focus {
outline:0;
}
.add-sticky {
cursor: default;
position:absolute;
top:1px;
left:1px;
font-size:200%;
background:#000;
color:#fff;
border:2px solid #fff;
border-radius:40px;
-webkit-border-radius:40px;
-moz-border-radius:40px;
text-align:center;
line-height:25px;
width:30px;
height:30px;
}
.add-sticky:hover {
background: #474747;
}
.sticky {
width:300px;
background:#fdfdbe;
box-shadow:3px 3px 10px rgba(0,0,0,0.45);
-webkit-box-shadow:3px 3px 10px rgba(0,0,0,0.45);
-moz-box-shadow:3px 3px 10px rgba(0,0,0,0.45);
}
.sticky-content {
min-height:150px;
border-left:3px double rgba(238, 150, 122, .75);
margin-left:30px;
padding:5px;
}
.sticky-header {
padding:5px;
background:#f3f3f3;
border-bottom:2px solid #fefefe;
box-shadow:0 3px 5px rgba(0,0,0,0.25);
-webkit-box-shadow:0 3px 5px rgba(0,0,0,0.25);
-moz-box-shadow:0 3px 5px rgba(0,0,0,0.25);
}
.sticky-status {
color:#ccc;
padding:5px;
}
.close-sticky {
background:#474747;
float:right;
cursor:default;
color:#ececec;
padding:1px 5px;
border-radius:20px;
-webkit-border-radius:20px;
-moz-border-radius:20px;
}

Тут є кілька цікавих моментів:

Деякі браузери роблять контур навколо елементів з contenteditable=true при редагуванні вами вмісту. Нам так не треба, так що позбавляємося від цього за допомогою оголошення :focus.

Кнопка «Add Sticky» (додати стікер) встановлена в верхньому лівому куті; виглядає смутно нагадує «Add Dashboard Widget» (додати віджет інструментальної панелі) у Mac OS X.

Ми користуємося властивостями CSS3 border-radius і box-shadow і відповідними префіксами для різних реалізацій браузерів.

Ми також використовуємо rgba() для відтінків тіні. Він приймає чотири параметри: червоний, зелений і синій колір і значення альфа (прозорість).

Інакше кажучи, це просто стандартний CSS. Ось як має виглядати замітка зі стилями:

Створення «клейких» нотаток, використовують локальну память

Крок 5: починаємо робити стікери

Тепер, коли ми зробили свій додаток, настав час запустити його; це можна зробити з пустого тега script в файлі index.html:

STICKIES.open();

Висновок.

Ось і все на сьогодні: як ви збираєтеся використовувати локальну пам’ять HTML5 для додавання родзинки в веб-проекти? Дайте мені знати про це у своїх коментарях!

Створення «клейких» нотаток, використовують локальну память

Переклад і редакція: Ріг Віктор і Андрій Бернацький. Команда webformyself.

E-mail: [email protected]

Проект webformyself.com — Як створити свій сайт. Основи самостійного сайтобудування

P. S. Хочете опублікувати цікавий тематичний матеріал і заробити? Якщо відповідь «Так», то тисніть сюди.