Permanente plaknotities bouwen met lokale opslag

HTML5 lokale opslag is als cookies op steroïden; het is ongelooflijk eenvoudig te gebruiken en toch zo krachtig. In deze zelfstudie laat ik u zien hoe u de 'plaknotities'-functionaliteit kunt creëren, waarmee uw gebruikers aanhoudende aantekeningen kunnen maken tijdens het browsen op uw site.


Stap 1: de HTML

Vanwege de dynamische aard van dit project, is er niet veel te coderen in de manier van reguliere oude semantische markup. We simuleren een webpagina gewoon door een aantal inhoud te vullen:

     HTML 5 voltooid      

Voorbeeld van artikeltitel

Lorem ipsum dolor ...

Copyright 2010 Andrew Burgess

Er zijn een paar belangrijke dingen om op te merken hier: we zijn inclusief twee CSS-bestanden: de eerste is de eenvoudige stijl van de pagina, die we hebben genoemd default.css. Dan hebben we een speciale CSS-bestanden voor stijlen met betrekking tot onze plaknotities; het heet stickies.css, en zoals je kunt zien, leeft het in de map "stickies". Onderaan staan ​​vier scripts:

  • jQuery, van het CDN van Google
  • JQuery UI, van het CDN van Google
  • JSON2, van Douglas Crockford
  • Ons eigen stickies.js, die in de map "stickies" leeft

Vervolgens hebben we een lege scripttag die we gebruiken om de motor een beetje later te starten.

En dat is het voor HTML!


Stap 2: De CSS

De inhoud van default.css is ongelooflijk eenvoudig:

 body marge: 0; padding: 0; achtergrond: #ccc; lettertype: 14px / 1.5 "Helvetica Neue", Helvetica, Arial, san-serif;  article, footer, header display: block;  artikel width: 880px; achtergrond: # fff; margin: auto; padding: 40px;  artikelkop kleur: # 474747; border-bottom: 1px solid # 474747 artikelfooter font-size: 90%; kleur: #ccc; 

Dat is het; nu is daar de CSS van stickies.css om voor te zorgen ... maar we hebben die markup nog niet. Dus laten we wat JavaScript starten, en als dat klaar is, kijken we naar de CSS voor de plaknotities.


Stap 3: JavaScript

Dit is het skelet voor onze JavaScript-toepassing:

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

We hebben hier een aantal interessante technieken. Ten eerste is de functie zelfintegratie: het lijkt erop dat we een functie toewijzen aan de variabele stickies, maar als u goed naar het einde van de functie kijkt, ziet u dat we het meteen uitvoeren. Als een hint - om ons eraan te herinneren dat dit geen normale functie is - wikkelen we de hele functie tussen haakjes. Zo, stickies is geen functie, het is de geretourneerde waarde van die functie, die in dit geval een object is.

Dat brengt ons bij de volgende techniek: sluiting. Merk op dat van de zes functies die we creëren, er slechts twee van hen aan de gebruiker worden blootgesteld (eigenlijk is er slechts één nodig voor het gebruik dat we plannen; als we ondersteuning wilden opbouwen voor het maken van notities op je website, zouden we de createSticky en deleteSticky). Hoewel de functie voor zelfintegratie is voltooid voordat we de methoden gebruiken, kunnen we de andere functies gebruiken die we hebben gedefinieerd.

Oké, laten we verder gaan met de inhoud van deze functie.


initStickies

We beginnen met het bekijken van de initStickies functie:

 var initStickies = function initStickies () $ ("
", text:" + "," class ":" add-sticky ", klik op: function () createSticky ();). prependTo (document.body); initStickies = null;,

Dit is vrij eenvoudig. We zullen jQuery gebruiken om elementen vrij veel te maken, en we gebruiken een speciale syntax in v. 1.4: dat geeft een letterlijk object door met de specs voor het element als een tweede parameter voor de jQuery-functie. Hier maken we een knop om een ​​nieuwe notitie te maken. Dat betekent dat we een nieuwe nodig hebben div; we zetten de tekst op "+" en geven hem een ​​klasse "add-sticky"; dan stellen we een click handler in om de createSticky methode (het is belangrijk om te bellen createSticky vanuit een functie, en niet direct naar de click handler bellen createSticky; dit is zo omdat createSticky kan één enkele parameter gebruiken en we willen niet dat dit het gebeurtenisobject is). Ten slotte zijn we dit aan het voorbereiden div naar het lichaam. We eindigen met instellen initStickies naar nul; ja, we raken in wezen weg van de functie die we gebruiken. Dit verzekert ons dat deze functie slechts eenmaal wordt uitgevoerd; we willen niet dat de gebruiker van onze API per ongeluk meerdere "notities toevoegen" -knoppen toevoegt aan de pagina.

openStickies

Laten we doorgaan naar de volgende methode, openStickies:

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

We beginnen met rennen initStickies... maar wat is de fraaie syntaxis? Wel, u bent waarschijnlijk bekend met && operator: de Boolean AND-operator. U zou het meestal gebruiken om meerdere voorwaarden in een if-verklaring te controleren. Dit is wat het feitelijk doet: het evalueert de eerste uitdrukking, en als dat uitkomt, zal het doorgaan met het evalueren van de tweede uitdrukking. In dit geval, als initStickies is nog niet ingesteld op null, we zullen de functie uitvoeren. Hiermee wordt de fout vermeden die zou ontstaan ​​als een nulvariabele als een functie wordt uitgevoerd.

Vervolgens doorlopen we elk item in localStorage. Dit is wat we doen in die for-loop (van binnen naar buiten):

  • localStorage.key () is een geweldige functie die de naam van de sleutel retourneert lokale opslag waarde; er is een nummer als een paramter voor nodig. Het is een geweldige manier om elk item om te lussen lokale opslag.
  • Zodra we de sleutel voor een opgeslagen item hebben, kunnen we deze doorgeven localStorage.getItem () om zijn waarde te krijgen.
  • Vervolgens geven we die waarde door aan JSON.parse (); dit komt uit de bibliotheek van Crockford. Omdat we een paar waarden opslaan voor elke notitie die we gebruiken JSON.stringify () aan de andere kant om een ​​object in een JSON-reeks te veranderen, die we opslaan. Hier zetten we het van een string terug naar een object.
  • Uiteindelijk geven we dat object door aan createSticky (), waardoor het weer een plakbriefje wordt.

createSticky

Laten we daar nu eens naar kijken createSticky methode.

 createSticky = function createSticky (data) data = data || id: + new Date (), top: "40px", links: "40px", tekst: "Note Here" return $ ("
", " class ":" sticky ", 'id': data.id) .prepend ($ ("
", " class ":" sticky-header ") .append ($ ("", " class ":" status-sticky ", klik op: saveSticky)) .append ($ ("", " class ":" close-sticky ", tekst:" trash ", klik op: function () deleteSticky ($ (this) .parents (". sticky "). attr (" id ")); ))) .append ($ ("
", html: data.text, contentEditable: true," class ":" sticky-content ", toetsaanslag: markUnsaved)) .draggable (handle:" div.sticky-header ", stack:" .sticky ", start: markUnsaved, stop: saveSticky) .css (position: "absolute", "top": data.top, "left": data.left). focus (saveSticky) .appendTo (document.body);,

Ja, het is lang, maar het zal niet al te moeilijk zijn. Merk allereerst op dat deze functie een data-object neemt; zoals we net zagen openStickies, we geven de opgeslagen gegevens door aan deze functie. Als we echter geen gegevens doorgeven (d.w.z. we maken een gloednieuwe notitie), maken we het standaardobjectobject. Omdat alle noten op één punt moeten worden aangemaakt, zullen alle noten met deze configuratie beginnen. Merk op dat we voor het noot-ID gebruiken +nieuwe datum(); De vooraf geplaatste operator unary plus converteert de datum die we van de nieuwe datum naar een nummer krijgen, dus deze verklaring resulteert in een getal dat het aantal milliseconden vertegenwoordigt sinds 1 januari 1970. Uiteraard zal dit aantal voortdurend veranderen, dus het is een geweldige manier om unieke identificatie van elke notitie.

De rest van de functie is een lange reeks van geketende jQuery-methoden. Voordat we dit doornemen, merken we op dat we het resultaat retourneren. Als we deze methode aan ontwikkelaars zouden blootstellen met behulp van onze mirco-API, zou het een verwijzing naar het element met de stick-note-div.

Dus, hier is wat er aan de hand is:

  • Eerst maken we de div dat is de schil van de plakbrief. Met behulp van die nuttige syntaxis van jQuery 1.4 geven we deze een klasse "plakkerig" en de id van het gegevensobject.

  • Vervolgens nemen we een div naar die; deze div krijgt een klasse "sticky-header". div.sticky-header krijgt dan twee spanwijdtes eraan toegevoegd. De eerste, span.sticky status, krijgt een click handler die de saveSticky functie. Maar dat is eigenlijk een verborgen functie: deze periode geeft de status van de sticky weer: opgeslagen of niet opgeslagen. Er zijn een paar manieren waarop de sticky zijn gegevens opslaat lokale opslag; het is mogelijk dat de gebruiker denkt dat het klikken op 'niet opgeslagen' de notitie zal opslaan, dus we zullen ze die functionaliteit bieden. De tweede span, span.close-sticky, is de knop Verwijderen: wanneer de gebruiker erop klikt, verwijderen we de stick van lokale opslag, via de deleteSticky methode. We geven die methode het noot-ID door.

  • Vervolgens voegen we nog een div toe aan de main div.sticky; merk op dat we de html eigendom aan data.text; wanneer we de tekst van de notitie opslaan, gebruiken we jQuery's html () methode, omdat gebruik tekst() verliest lijnbreuk. We hebben ook vastgesteld contentEditable: true op deze div, omdat dit de inhoud van de notitie is. Als zodanig krijgt het ook de klasse sticky-inhoud. Ten slotte, wanneer een toets wordt ingedrukt op deze div (wat betekent dat de gebruiker de inhoud wijzigt), willen we deze markeren als niet opgeslagen, dus we zullen die functie noemen (die we binnenkort zullen maken).

  • Nu gebruiken we de dragible-functie jQuery UI om onze plaknotitie verplaatsbaar te maken. In ons parameterobject gebruiken we de handvat eigenschap om onze aantekeningen alleen verplaatsbaar te maken vanuit de headerbalk. De stack eigenschap is een selector voor de versleepbare elementen die willen "stapelen"; door dit in te stellen, komt de momenteel gesleepte notitie altijd naar de top. Eindelijk, wanneer we beginnen met het slepen van de notitie, willen we deze markeren als "niet opgeslagen" (omdat we ook de coördinaten moeten opslaan) en als we stoppen met slepen, redden we die plakkerig.

  • Vervolgens stellen we enkele stijlen in voor onze div.sticky; we positioneren het absoluut en stellen dan de bovenste en linker waarden in op die in het data-object. Op deze manier behoudt de notitie zijn positie evenals de inhoud ervan wanneer we de pagina vernieuwen.

  • Ten slotte stellen we een gebeurtenishandler in voor wanneer we focusOut van de plakkerige (in wezen, klik er buiten na het klikken in het): we willen de plakkerig bewaren. Ten slotte voegen we het toe aan het lichaam. Ter referentie, hier is de html-structuur die we zouden moeten genereren:

uitschot
Noteer hier

En dat is onze createSticky functie.

deleteSticky

Nu hebben we de deleteSticky functie; het is echt eenvoudig:

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

Zoals u zich herinnert, de deleteSticky functie neemt de id van een notitie als zijn parameter. localStorage.removeItem () is de methode van het uur: we geven het de sleutel door aan een lokaal opgeslagen waarde om dat sleutel / waarde-paar te verwijderen (merk op dat wanneer we de notitiegegevens opslaan, we "sticky-" aan de id plakken). Vervolgens vinden we het element met de gegeven id, vervagen het en verwijderen we het. Opmerking verwijderd!

saveSticky

Voor de laatste keer is misschien de belangrijkste methode: saveSticky: dit is de lijm die ervoor zorgt dat alles werkt.

 saveSticky = function saveSticky () var that = $ (this), sticky = (that.hasClass ("sticky-status") || that.hasClass ("sticky-content"))? that.parents ('div.sticky'): dat, obj = id: sticky.attr ("id"), top: sticky.css ("top"), links: sticky.css ("left"), tekst : sticky.children (". sticky-content"). html () localStorage.setItem ("sticky-" + obj.id, JSON.stringify (obj)); . Sticky.find ( "sticky-status ") tekst (" gered"); ,

De eerste regel is een beetje een resolutie: er zijn drie verschillende elementen waaruit we deze functie kunnen noemen. Eerst zullen we "jQuerify" deze in dat; Als het element de klassen 'Sticky-status' of 'Sticky-content' heeft, krijgen we de bovenliggende kolom div.sticky; als het geen van beide klassen heeft, dan is het dat wel div.sticky zelf, dus we zullen dat gewoon gebruiken.

Vervolgens moeten we de waarden krijgen die we willen opslaan. Zoals u kunt zien, krijgen we de ID, offset van de boven- en linkerkant, en de HTML van het kind .sticky-inhoud; onthoud dat we gebruiken html () in plaats van tekst() omdat we de regeleinden willen behouden. Vervolgens gebruiken we localStorage.setItem om de gegevens op te slaan. Onthoud dat er twee parameters nodig zijn: de sleutel en de waarde die moet worden opgeslagen. Sinds lokale opslag slaat alleen strings op, die we gebruiken JSON.stringify () om het object naar een string te converteren.

Wijzig ten slotte de sticky-status in 'saved'.

markUnsaved

We hebben nog een laatste functie, die slechts een hulpfunctie is:

 markUnsaved = function markUnsaved () var that = $ (this), sticky = that.hasClass ("sticky-content")? that.parents ("div.sticky"): dat; sticky.find ( "sticky status. ") tekst (" opgeslagen").; 

Nogmaals, we moeten beginnen met het oplossen van de verwijzing naar div.sticky; Zodra we dit doen, kunnen we eenvoudig de statusspanne vinden en de tekst instellen op 'niet opgeslagen'.

Geloof het of niet, dat is al het JavaScript.


Stap 4: De CSS, Revisited

Nu we weten wat onze plaknotitieopmaak is, kunnen we het opmaken. Het is vrij eenvoudig; maar kijk er eens over, en ik zal aan het eind een paar opmerkingen maken:

 : focus overzicht: 0;  .add-sticky cursor: standaard; positie: absoluut; top: 1px; left: 1px; font-size: 200%; achtergrond: # 000; color: # fff; border: 2px solid #fff; border-radius: 40px; -webkit-border-radius: 40px; -moz-border-radius: 40px; text-align: center; line-height: 25 pixels; width: 30px; hoogte: 30px;  .add-sticky: hover background: # 474747;  .sticky width: 300px; achtergrond: #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-gehalte min-height: 150px; border-links: 3px dubbele rgba (238, 150, 122, .75); margin-left: 30px; padding: 5px;  .sticky-header opvulling: 5px; background: # f3f3f3; border-bottom: 2px solid #fefefe; vakschaduw: 0 3px 5px rgba (0,0,0,0.25); -webkit-vak-schaduw: 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: standaard; kleur: #ececec; opvulling: 1px 5px; border-radius: 20px; -webkit-border-radius: 20px; -moz-border-radius: 20px; 

Er zijn een paar aandachtspunten hier:

  • Sommige browsers zetten een omtrek rond elementen met contenteditable = true wanneer je de inhoud aan het bewerken bent. We willen dat niet, dus we doen het weg met onze :focus verklaring.
  • De knop "Sticky toevoegen" bevindt zich in de linkerbovenhoek; het lijkt vaag op het "Dashboard Widget toevoegen" in Mac OS X.
  • We gebruiken de CSS3-eigenschappen met randradius en vakschaduw (en de bijbehorende inclusies van de leverancier-prefix).
  • We gebruiken ook RGBA () voor onze schaduwkleuren. Er zijn vier parameters nodig: de rode, hebzuchtige en blauwe kleuren en de alpha (transparantie) -waarde.

Anders dan dat, het is gewoon je standaard CSS. Dit is wat een gestileerde notitie eruit zou moeten zien:


Stap 5: De Stickies starten

Nu we onze API hebben gemaakt, is het tijd om het op te starten; we kunnen dat doen vanuit het extra lege script tag in onze index.html het dossier:

 STICKIES.open ();

Conclusie: het eindproduct

Nou, we zijn klaar! Dit is het uiteindelijke product in actie:

Dat is alles wat ik heb voor vandaag; Hoe bent u van plan om HTML5-lokale opslag te gebruiken om uw webprojecten te verfraaien? Laat het me weten in de comments!