senäh

17senäh und so…

Artikelbild: Einfache To-Do-Liste im Notizbuch-Design

HTML/CSS/JS
22. Mrz 2012
Kommentare: 7

Einfache To-Do-Liste im Notizbuch-Design

Kategorien: HTML/CSS/JS | 22. Mrz 2012 | Kommentare: 7

Durch einen bei css-tricks veröffentlichten Artikel wurde ich dazu inspiriert, mich kurz in viererlei Sachen zu üben:

  • CSS mit Transitions und Pseudo-Elementen
  • möglichst wenig HTML-Markup
  • keine Bilder verwenden
  • einfaches JavaScript ohne jQuery & Co

Herausgekommen ist einer sehr einfache To-Do-Liste im Notizbuch-Stil. Kleine Spielerei, aber ein bisschen was habe ich gelernt. Vor allem, dass man JavaScript völlig neu lernen muss, wenn man sonst nur den Umgang mit jQuery gewohnt ist.

Es folgt ein kleiner Walkthrough.

Ziel…

… sieht so aus:

So sieht die fertige Liste aus

So sieht die fertige Liste aus

Wie gesagt, eine To-Do-Liste im Notizbuch-Stil. Hellgrauer Hintergrund, erledigte Aufgaben werden markiert und ein paar Hover- und Klick-Effekte.

HTML

Eine einfache Liste. Da man das Ganze eventuell um eine weitere Liste für gelöschte Aufgaben o.ä. erweitern möchte, verwenden wir eine Klasse statt einer ID.

1
2
3
4
5
6
7
8
9
10
11
12
13
<ul class="list">
    <li>Frühstück</li>
    <li>Facebook checken</li>
    <li>Rasieren</li>
    <li>Müll runterbringen</li>
    <li>Mama anrufen</li>
    <li>Twittern, dass ich Mama angerufen habe</li>
    <li>über Kontostand wundern</li>
    <li>Fernsehprogramm durchstöbern</li>
    <li>einen sehr langen Aufgabentext ausdenken, um die Einzeiligkeit zu demonstrieren</li>
    <li>Gute Nacht Geschichte anhören</li>
    <li>Schäfchen zählen und zZz</li>
</ul>

That’s it.

JavaScript

Ich komme erst zum JavaScript, weil wir hier lediglich Klassen wechseln. Um das Styling kümmern wir uns im Anschluss.

Eine Aufgabe hat 2 mögliche Zustände: erledigt oder unerledigt. Im ersteren Fall soll das entsprechende Listen-Element die Klasse done erhalten. Falls es doch wieder als unerledigt markiert werden soll, muss die Klasse gelöscht werden.

In jQuery würde man wohl sowas in der Art schreiben:

1
2
3
$('.list li').click(function(){
    $(this).toggleClass('done');
});

Da ich aber für so eine popelige To-Do-Liste keine extra Bibliothek einbinden möchte, soll das Ganze doch bitte über natives JavaScript realisiert werden. Hier der Code dafür, Erklärung ist drunter.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function addLinkEvt() {
    // getElementsByClassName returns nodeList we have to walk through!
    var lists = document.getElementsByClassName('list');
    for (var i = 0; i < lists.length; i++) {
        var listElements = lists[i].getElementsByTagName('li');
        for (var j = 0; j < listElements.length; j++) {
            listElements[j].addEventListener('click', toggleDoneClass, false);
        }
    }
}

function toggleDoneClass(e) {
    var elem = e.target;
    var doneClass = 'done';
    elem.className = (elem.className == '') ? doneClass : '';
}

window.onload = addLinkEvt;

Im Nachhinein nur logisch. Wenn man aber wie bereits erwähnt sonst nur mit jQuery unterwegs ist, stößt man auf ein paar Stolpersteine. Zuerst holen wir uns mit getElementsByClassName('list') alle Listen. Danach schauen wir mit einer for-Schleife auf alle Listen-Elemente und fügen ein Klick-Event hinzu. Die dabei aufgerufene Funktion toggleDoneClass() imitiert dann das Verhalten von jQuery’s toggleClass().

Zu guter Letzt müssen wir mit onload noch sicherstellen, dass das Event-Binding auch durchgeführt wird.

CSS

Jetzt zum lustigen Teil ;) Interessant sind dabei die Transitions, wenn man über eine Aufgabe fährt, das Zusammenspiel von Häkchen und X beim Markieren der Aufgaben sowie der roten Doppelrand ohne zusätzliches Markup.

Ich zeige euch jetzt einfach mal das CSS komplett. Die Kommentare sollten alles verständlich machen. Hoffentlich stört ihr euch nicht an dem Englisch. Habe ich mir so angewöhnt :)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
body {
    background-color:#f5f5f5;
    width:600px;
    margin:0 auto;
    padding:0;
}
.list {
    position:relative; /* so our red line will be positioned correctly */
    color:#555;
    font-size:22px;
    padding:0;
    width:500px;
    font-family:courier, monospace;
    border:1px solid #dedede;
}
/* red border on the left side */
.list:before {
    content:"";
    position:absolute;
    z-index:99;
    top:-1px;
    left:40px;
    height:100%;
    width:2px; /* important for doubled border to work */
    border-left:1px solid #ffaa9f;
    border-right:1px solid #ffaa9f;
}
.list li {
    position:relative; /* so ✔/✖ will be positioned correctly */
    list-style:none;
    height:auto;
    padding:10px 10px 10px 80px;
    border-bottom:1px dotted #ccc;
    cursor:pointer;
    /* following 3 lines will prevent our list elements from being multiline */
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
/* green background for tasks marked "done" */
.list li.done {
    background-color:#dfd;
}
/* get rid of the last line's bottom-border */
.list li:last-child {
    border-bottom:none;
}
/* fancy new css transitions */
.list li:hover {
    background-color:#f0f0f0;
    -webkit-transition:all 0.2s;
    -moz-transition:all 0.2s;
    -ms-transition:all 0.2s;
    -o-transition:all 0.2s;
}
/* show ✔ on hover */
.list li:hover:before {
    content:"✔";
    color:#090;
    position:absolute;
    top:10px;
    left:12px;
}
/* keep green background for done tasks on hover */
.list li.done:hover {
    background-color:#dfd;
}
/* permanently show ✔ for tasks marked "done" */
.list li.done:before {
    content:"✔";
    color:#090;
    position:absolute;
    top:10px;
    left:12px;
}
/* show red ✖ on hover if task is marked "done" */
.list li.done:hover:before {
    content:"✖";
    color:#c00;
}

Die Symbole für Haken und Kreuz (einzeln, nicht in Kombination) gibt’s hier. Übrigens einer meiner Lieblings One-Page-Apps.

Demo…

gibt’s hier ;)

Wie man also sieht: eine simple To-Do-Liste ohne Grafiken und ohne externe Dateien. Für mich eine schöne Übung. Ließe sich – wie eingangs erwähnt – auch noch ein wenig erweitern. Das überlasse ich aber euch ;)

Seht euch auch bei Interesse die Kommentare zum Original-Artikel an. Der Artikel selbst war btw ein Gastbeitrag eines – wait for it – 14-Jährigen! Das Einzige, was ich in dem Alter am Rechner gemacht hab, war das verzweifelte Sammeln von S-K-A-T-E bei Tony Hawk’s Pro Skater 2 :D

Autor: Enno

Ich bin Enno. PHP ist mein Ding, aber auch alles Neue rund um die Themen HTML5, CSS3 & Co finde ich interessant. Ich mag es Leuten zu helfen und mein Wissen weiterzugeben. Sollte dir mein Beitrag gefallen haben, lass doch nen Kommentar da oder benutze einen der Social Buttons, um deinen Dank auszudrücken ;)

Kommentare (7)

  1. Gefällt mir übrigens super gut der Artikel :) Hab’s dir bisher noch nicht gesagt ;)

  2. Schöner Beitrag :D

    Ich hab die Liste eben auch noch ein wenig modifiziert. 

    So schaut das bis jetzt aus : http://jsfiddle.net/Akkumulator/jJUmB/41/embedded/result/

    • Wow, gefällt mir richtig gut. Die Sache mit der automatischen Ordnung und vor allem dem Verschieben ist ziemlich cool.

      Das Eingabefeld hätte ich wohl eher weiß gehalten. Gelb als Signalfarbe ist für die Drop-Area beim Verschieben der Todos genau richtig, beim Eingabefeld funktioniert weiß mMn besser. Der Plus-Button ist bei mir ein wenig nach unten verrutscht. Und die unten angepriesene Wischgeste funktioniert bei mir nicht (oder ist stelle mich zu doof an :D).

      Bis auf diese kleinen Schönheitsfehler eine ordentliche Erweiterung dieses kleinen Experiments, vielen Dank :) 

    • Danke für deine Anregungen. :)

      Bezüglich der gelben Hintergrundfarbe stimme ich dir zu, weiß passt da wohl besser.

      Das mit dem Button ist mir auch schon aufgefallen. Ich habe dazu das: http://christophzillgens.com/en/articles/equal-height-input-and-button-elements-in-firefox-and-safari
      gefunden. Hilft aber z. B. im Chrome nix… 
      Da die Elemente im CSS die gleiche Höhe haben weiss ich auch nicht woher das kommt… (Anregungen Wilkommen :D )

      Das Wischen ist vor allem fürs Touch Device gedacht. Funktioniert bei mir aber auch am Desktop.

      Da ich am Wochenende etwas Zeit hatte, hab ich gleich noch ne für touch optimierte Liste erstellt :D
      Geblieben ist die Schriftart und die Idee einer ToDo Liste :) http://www.screenr.com/ZDh7

    • Zu dem Button-Problem: lass einfach beide Elemente links floaten, also sowohl das input als auch den Button. Die <ul> danach musst du dann entsprechend clear:both setzen.

      Gibt es eigentlich einen Grund dafür, dass du button statt input[type=”submit”] genommen hast? Dachte ersteres wäre irgendwann ausgestorben, sehe es aber in letzter Zeit immer öfter.

      Wischen funzt bei mir im Chrome wie gesagt nicht, keine Ahnung warum.

      Zur Touch-Liste: in dir steckt viel Dev-Energie, nutze sie sinnvoll :) Die App wirkt etwas laggy, kann aber auch gern an der Screencast-Software liegen. Was hast du benutzt?

      Beim nächsten Mal wäre vielleicht auch ein Finger-Tracker ganz sinnvoll, damit man genau sieht, was dein “Eingabegerät” macht.

      Viele Grüße und danke für’s Teilen,
      Enno

    • Hab den Button in Input umgewandelt, somit kann man die Eingabe auch mit ‘return” am Smartphone abschicken.
      Den Screencast hab ich schnell mit http://www.screenr.com/ in Verbindung mit Airplay gemacht. Das laggen liegt in der tat am Screencast :)

Hinterlasse einen Kommentarsenäh

Pflichtfelder sind mit * markiert.