Создание постоянных липких заметок с локальным хранилищем

20 января 2018

локальное хранилище HTML5 похоже на файлы cookie на стероидах; он невероятно прост в использовании и все же настолько силен. В этом уроке я покажу вам, как создать функциональность «заметных заметок», которая позволяет вашим пользователям принимать постоянные заметки во время просмотра вашего сайта.


Шаг 1: HTML

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

<!DOCTYPE html>
  <html>
  <head>
      <meta charset='utf-8' />
      <title>HTML 5 complete</title>
      <link rel="stylesheet" href="default.css" />
      <link rel="stylesheet" href="stickies/stickies.css" />
      <!--[if IE]>
      <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
      <![endif]-->
  </head>
  <body>
      <article>
          <header>
              <h1> Sample Article Title</h1>
          </header>
          <p>Lorem ipsum dolor. . . </p>
          <!-- a few lorem-ipsum paragraphs later . . . -->
          <footer>
              <p>Copyright 2010 Andrew Burgess</p>
          </footer>
      </article>
      <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
      <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.min.js"></script>
      <script src="json2.js"></script>
      <script src="stickies/stickies.js"></script>
      <script>
      </script>
  </body>
  </html>

Здесь есть несколько важных вещей: мы включаем два файла CSS: первый - это простой стиль для страницы, который мы назвали default.css. Затем у нас есть специальные файлы CSS для стилей, относящихся к нашим липким заметкам; он называется stickies.css, и, как вы можете видеть, он живет в папке «stickies». Внизу мы включаем четыре сценария:

jQuery, из пользовательского интерфейса Google CDN JQuery от CDN JSON2 от Google, от Дугласа Крокфорда. Наши собственные stickies.js, которые живут в каталоге «липкие»

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

И это для HTML!


Шаг 2: CSS

Содержимое default.css невероятно просто:

body {
     margin:0;
     padding:0;
     background:#ccc;
     font:14px/1.5 "Helvetica Neue", Helvetica, Arial, san-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 не является функцией, это возвращаемое значение из этой функции, которая является объектом, в этом случае.

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

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


initStickies

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

var initStickies = function initStickies() {
    $("<div />", {
        text : "+",
        "class" : "add-sticky",
        click : function () { createSticky(); }
    }).prependTo(document.body);
    initStickies = null;
},

Это довольно просто. Мы будем использовать jQuery для создания элементов совсем немного, и мы используем специальный синтаксис в версии 1.4: это передача литерала объекта со спецификациями для элемента в качестве второго параметра функции jQuery. Здесь мы создаем кнопку для создания новой заметки. Это означает, что нам нужен новый div; мы устанавливаем текст в «+» и придаем ему класс «add-sticky»; то мы устанавливаем обработчик кликов для вызова метода createSticky (важно вызвать createSticky изнутри функции и не иметь прямого вызова обработчика clickSticky, потому что createSticky может принимать один параметр, и мы не делаем этого, t хочу, чтобы это был объект события). Наконец, мы добавим этот div в тело. Мы заканчиваем настройкой initStickies на null; да, мы по существу избавляемся от функции, которую мы запускаем. Это гарантирует, что эта функция будет запускаться только один раз; мы не хотим, чтобы пользователь нашего API нечаянно добавлял несколько кнопок «добавить примечание» на страницу.

openStickies

Перейдем к следующему методу, openStickies:

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

Начнем с запуска initStickies... но что с сильным синтаксисом? Ну, вы, вероятно, знакомы с оператором &&: логическим оператором AND. Вы обычно использовали его для проверки нескольких условий в if-statement. Вот что он на самом деле делает: он оценивает первое выражение, и если это получится истинным, оно продолжит оценивать второе выражение. В этом случае, если initStickies еще не установлен в значение null, мы запустим эту функцию. Это позволяет избежать ошибки, возникающей при попытке запуска нулевой переменной как функции.

Затем мы перебираем каждый элемент в localStorage. Вот что мы делаем в этом for-loop (изнутри внутрь):

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

createSticky

Теперь давайте посмотрим на этот метод createSticky.

createSticky = function createSticky(data) {
    data = data || { id : +new Date(), top : "40px", left : "40px", text : "Note Here" }
    return $("<div />", {
        "class" : "sticky",
        'id' : data.id
         })
        .prepend($("<div />", { "class" : "sticky-header"} )
            .append($("<span />", {
                "class" : "status-sticky",
                click : saveSticky
            }))
            .append($("<span />", {
                "class" : "close-sticky",
                text : "trash",
                click : function () { deleteSticky($(this).parents(".sticky").attr("id")); }
            }))
        )
        .append($("<div />", {
            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, мы передаем сохраненные данные этой функции. Однако, если мы не передаем какие-либо данные (т. Е. Создаем совершенно новую заметку), мы создадим объект примечания по умолчанию. Поскольку все заметки должны быть созданы в какой-то момент, все ноты начнутся с этой конфигурации. Обратите внимание, что для идентификатора примечания мы используем + новую Date (); что добавочный оператор унарного плюс преобразует дату, которую мы получаем от новой даты, к числу, поэтому это выражение приводит к числу, представляющему число миллисекунд с 1 января 1970 года. Очевидно, что это число будет постоянно меняться, поэтому это отличный способ однозначно идентифицировать каждую ноту.

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

Итак, вот что происходит:

Во-первых, мы создаем div, который является оболочкой липкой заметки. Используя этот полезный синтаксис jQuery 1.4, мы даем ему класс «липкий» и идентификатор из объекта данных. Затем мы добавим div к этому; этот div получает класс «sticky-header». div.sticky-header затем добавляет два расширения. Первый, span.sticky-status, получает обработчик клика, который вызывает функцию saveSticky. Однако на самом деле это скрытая функция: этот диапазон отображает статус липкой: сохраненной или несохраненной. Будет несколько способов, чтобы липкая информация сохранялась в localStorage; возможно, что пользователь подумает, что нажатие «unsaved» сохранит заметку, поэтому мы предоставим им эту функциональность. Второй диапазон, span.close-sticky, будет кнопкой delete: когда пользователь нажмет на него, мы удалим липкий из localStorage с помощью метода deleteSticky. Мы передаем этот метод идентификатору примечания. Затем мы добавляем другой div к основному div.sticky; обратите внимание, что мы установили свойство html в data.text; когда мы сохраняем текст примечания, мы используем метод html () jQuery, потому что использование text () избавляется от разрывов строк. Мы также устанавливаем contentEditable: true в этом div, потому что это содержание заметки. Таким образом, он также получает класс липкого контента. Наконец, когда клавиша нажата на этот div (что означает, что пользователь меняет содержимое), мы хотим пометить его как несохраненную, поэтому мы будем называть эту функцию (которую мы сделаем в ближайшее время). Теперь мы используем функцию jQuery UI draggable, чтобы сделать нашу липкую заметку подвижной. В нашем объекте параметра мы используем свойство handle, чтобы наши заметки перемещались только с панели заголовка. Свойство stack - это селектор для перетаскиваемых элементов, которые хотят «стекать»; установив это, текущая перетаскиваемая заметка всегда будет на вершине. Наконец, когда мы начинаем перетаскивать заметку, мы хотим пометить ее как «несохраненную» (потому что нам тоже нужно сохранить ее координаты), и когда мы перестанем перетаскивать, мы сохраним эту липкость. Затем мы устанавливаем некоторые стили для нашего div.sticky; мы устанавливаем его абсолютно, а затем устанавливаем его верхнее и левое значения в те, которые содержатся в объекте данных. Таким образом, заметка сохранит свою позицию, а также ее содержимое, когда мы обновим страницу. Наконец, мы установим обработчик событий, когда мы сосредоточимся на липкой (по существу, закройте ее после нажатия внутри нее): мы хотим сохранить липкий. Наконец, мы добавим его в тело. Для справки, вот структура html, которую мы должны были сгенерировать:

<div class="sticky ui-draggable" id="1281194825332" style="position: absolute; top: 40px; left: 40px;">
    <div class="sticky-header">
            <span class="sticky-status"></span>
            <span class="close-sticky">trash</span>
    </div>
    <div contenteditable="true" class="sticky-content">
        Note Here
    </div>
</div>

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

deleteSticky

Теперь у нас есть функция deleteSticky; это очень просто:

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

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

saveSticky

Сегодня самым последним может быть самый последний метод: 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");
},

Первая строка немного разрешена: из этой функции можно вызвать три разных элемента. Во-первых, мы будем «jQuerify» в этом; то, если у элемента есть классы «липкий статус» или «липкий контент», мы получим родительский div.sticky; если он не имеет ни одного из этих классов, тогда он сам div.sticky, поэтому мы просто будем использовать это.

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

Наконец, измените липкий статус на «сохраненный».

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; как только мы это сделаем, мы можем просто найти интервал состояния и задать текст «несохраненным».

Верьте или нет, это все JavaScript.


Шаг 4: CSS, Revisited

Теперь, когда мы знаем, что такое наша заметная заметка, мы можем ее стилизовать. Это довольно просто; но посмотрим, и я сделаю несколько комментариев в конце:

: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. Кнопка «Добавить липкую» находится в верхнем левом углу; он выглядит смутно похожим на «Добавить виджет панели» в Mac OS X. Мы используем свойства CSS3 с граничным радиусом и квадратной тканью (и их соответствующие воплощения преемника поставщика). Мы также используем rgba () для наших теневых цветов. Он принимает четыре параметра: красный, жадный и синий цвета, а также значение альфа (прозрачность).

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


Шаг 5: Запуск Stickies

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

STICKIES.open();

Вывод: конечный продукт

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

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