Akordeon

Przyznam się, że nie wiedziałem jak nazwać tą notkę także wybaczcie mi to ;-) Chciałem napisać (specjalnie na prośbę Grzegorza Piechuły ;-] ) sposób w jaki przedstawione są u mnie notatki z minibloga.

Cel jaki chcemy osiągnąć to warstwa (w niej będzie treść notek), która zwija się i rozwija. Poza tym zrobimy tak, że gdy jedna notka będzie rozwinięta, a chcemy zobaczyć drugą to ta pierwsza posłusznie się zwinie, a dopiero później pokaże się druga.

Całość oparłem o framework jQuery, także należy się w niego wyposażyć. Na początku zaczniemy od zakodowania naszych notek:

<div id="notes">
        <h3>Nagłówek 1</h3>
        <div>
                <p>
                Lorem ipsum dolor sit amet, consectetuer adipiscing elit. 
                Morbi vel elit vel nulla accumsan euismod. 
                Cras nulla elit, aliquam placerat, consectetuer pulvinar, mattis in, lacus. 
                Maecenas nulla sapien, sollicitudin id, gravida non, porttitor quis, sapien.
                </p>
                <p class="up">[zamknij]</p>
        </div>
        
        <h3>Nagłówek 2</h3>
        <div>
                <p>
                Maecenas sed magna adipiscing justo facilisis volutpat. Maecenas at tellus. Aliquam erat volutpat.
                Morbi lobortis viverra urna. Sed non augue quis justo adipiscing blandit. 
                Aenean eros turpis, aliquet ac, adipiscing ut, porta mollis, ante.
                Aenean massa massa, faucibus ut, lacinia sed, dictum vitae, nulla.
                </p>
                <p class="up">[zamknij]</p>
        </div>
</div>

Poza tym możemy jeszcze ładnie opisać CSSem nasze notatki tak, żeby ładniej wyglądały ;-) Tak na stronie będą się one prezentowały na przeglądarkach, które nie korzystają, lub mają wyłączoną obsługę JavaScript.

Chciałem od razu uprzedzić, że blok z klasą “up” będzie służył do zamykania otwartych okienek, także na samym początku warto w stylach dopisać do tej klasy (“.up”) display na none tak aby blok niepotrzebnie pokazywał się w przeglądarce bez JSa.

Dla tych, którym nie chce się pisać wszystkiego zapraszam tutaj.

Teraz przejdziemy do kolejnego kroku. Dołączymy jQuery, oraz zapiszemy pierwsze linijki kodu, który “ułoży” nasze notatki w jednym miejscu oraz je schowie.

W sekcji head dopisujemy:

<script src="/sciezka/do/jquery.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(
function()
{
        // (...) <- tutaj będziemy wstawiali nasz kod ;-]
}
);
</script>

Do arkusza stylów dopisujemy klasę dla bloków div, w których są notki. Ta klasa będzie nadawała każdej notce pozycję absolutną (gdyby co chodzi o position:absolute; ;-] ), oraz będzie chowała w/w notki. Na potrzeby tego tekstu tą klasę nazwę po prostu “j”.

Nasz skrypt, zaraz po załadowaniu drzewa DOM, musi nadawać wszystkim notkom klasę “j” (tak aby ją schować), oraz pokazać bloki z klasą “up”, tak aby były widoczne po rozwinięciu notki. Przypominam, że bloki z klasą “up” będą służyły do zamykania rozwiniętych notatek.

$("#notes > div").addClass("j");
$("#notes p.up").show();

Teraz nadajemy zdarzenie click nagłówkom h3, które będzie pokazywało odpowiednie notki. Przy okazji nadamy blokom z klasą “up” zdarzenie click, po którym nasza notka schowie się.

$("#notes").children("h3").click(
function()
{
        $(this).next("div").slideToggle("normal");
        $("#notes > h3").not(this).next("div:visible").slideUp("fast");
}
);
$("#notes p.up").click(
function()
{
        $(this).parent().slideUp("normal");
}
);

Demo

Niestety jeszcze nie osiągnęliśmy do końca oczekiwanego efektu. Wprawdzie notka się rozwija, zwija itd… Problem jest w tym, że gdy chcemy zobaczyć drugą notkę, podczas gdy pierwsza jest widoczna, to jedna notka zwija się przy czym jednocześnie druga się rozwija. My chcemy zrobić tak aby najpierw pierwsza notka się zwinęła, a dopiero później druga się rozwinęła.

Można by było kombinować z wykorzystaniem jakiś funkcji typu sleep(), jednak gdy do metody slideUp (i nie tylko tej) przekażemy drugi parametr (pierwszy to prędkość zwijania/rozwijania) jako funkcję, zostanie ona wykonana po zakończeniu zwijania.

Brzmi strasznie? Na szczęście tak nie jest ;-) Zmienimy zdarzenie click nadane elementowi h3.

Problemem jest to jak sprawdzić czy już jakiś div jest rozwinięty. Na szczęście możemy wykorzystać metodę is(), która zwraca wartość TRUE, lub FALSE, a korzystamy z niej podobnie jak z metody filter().

Jakoś nie potrafię opisać wszystkiego słowami także przedstawię kod, a w komentarzach opiszę całość.

$("#notes").children("h3").click(
function()
{
        var tmp = $(this); // musimy przypisać obiekt do zmiennej pomocniczej, ponieważ w innym wypadku nie uda nam się rozwinąć notki
        if( $(this).next("div").is(":visible") )
        {
                // Jeśli notka o wybranym tytule już była pokazana, w tym momencie zostanie schowana
                $(this).next("div").slideUp("normal");
        }
        else if( $("#notes h3").next("div").is(":visible") )
        {
                // zwinięcie rozwiniętej notki, a dopiero pozniej rozwiniecie kolejnej
                $("#notes h3").next("div:visible").slideUp("normal",
                        function() { tmp.next("div").slideDown("normal"); }
                        // w tym miejscu wykorzystujemy właśnie zmienną pomocniczą _tmp_
                        // bez niej niesety nie byłoby możliwe rozwinięcie nowej notki
                );
        }
        else
        {
                $(this).next("div").slideDown("normal");
                // Jesli nie ma zadnej notki, ta zostanie rozwinięta
        }
}
);

Demo

To by było tyle. Wiem, że nie potrafię dobrze takich rzeczy opisywać, ale uwierzcie – starałem się.

22 Responses to “Akordeon”

  1. Piechuła September 23, 2007 at 1:20 am #

    Kocham Cię :*

    :D

  2. radmen September 23, 2007 at 1:20 am #

    Ja już mam kogoś ;-]

  3. _kUtek_ September 23, 2007 at 1:20 am #

    mnie. :]

  4. radmen September 23, 2007 at 1:20 am #

    Cii miałeś być dyskretny!

  5. _kUtek_ September 23, 2007 at 1:20 am #

    Już nie mogę tego dłużej ukrywać..

  6. radmen September 23, 2007 at 1:20 am #

    Ale ja Ciebie nawet nie widziałem..

  7. _kUtek_ September 23, 2007 at 1:20 am #

    bo ja jestem botem, stworzył mnie ukraiński uczony, ale gdy poznał mnie bliżej – porzucił. Od tego czasu szukam mojego nowego mistrza, mojej nowej miłośći. I znalazłem Ciebie.

  8. radmen September 23, 2007 at 1:20 am #

    /bot destroy ? :>

  9. _kUtek_ September 23, 2007 at 1:20 am #

    musisz wpisać to po ukraińsku. :-P

  10. Koval September 23, 2007 at 1:20 am #

    moo tool by sie jeszcze przydało

  11. night September 23, 2007 at 1:20 am #

    To była ciepła, pogodna noc 22/23 września 2007 roku. Night siedząc w swoim przepastnym fotelu i oglądając swojego joggera pomyślał: „chcę mieć rozwijane notki”. Posiedział nad tym 20 minut, po czym zrezygnowany udał się na ostatniego papierosa w tym dniu i zasnął.

    23 września 2007 roku, iGoogle powiadomiło go o nowym wpisie na techblogu „Rozwijane notki”….

    Masz piwo stary! Masz piwo :-) z nieba mi spadłeś z tym wpisem :D :*

  12. D4rky September 23, 2007 at 1:20 am #

    Radmen – czym kolorujesz kod?
    Kutek – бот знищують

  13. night September 23, 2007 at 1:20 am #

    Właśnie radmen, czym kolorujesz składnię? ja się ostatnio dobrałem do googlowego projektu dp.SyntaxHighlighter (chyba googlowego) ale wygląd tego skryptu u Ciebie bardziej mi się podoba :-)

  14. radmen September 23, 2007 at 1:20 am #

    Korzystam z google code prettify , z dodaniem tła dla elementu code :)

  15. Łukasz :] September 23, 2007 at 1:20 am #

    Ty mi lepiej powiedz, jak zrobiłeś takie menu, tak pięknie rozwijane, bo się zakochałem <3333333

  16. Riddle September 23, 2007 at 1:20 am #

    To się akordeon zwie a nie zwijalne notki. :D Ale good job :)

  17. _kUtek_ September 23, 2007 at 1:20 am #

    Coś tu sobie było.
    Zniknęło – bo wytłumaczli mi, dlaczego durniem jest. ;-)

  18. D4rky September 23, 2007 at 1:20 am #

    Kutek – duren. Takich linkow sie nie daje _

  19. inina September 23, 2007 at 1:20 am #

    Panowie, mam prośbę. To zrozumiałe, że podkochujecie się w Radmenie,ale zachowajcie tę wiadomość dla siebie. Pogaduchy o zwijanej notce, to tylko przykrywka! No, zazdrosna jestem… Te wszystkie serduszka i buziaczki… Co ja mam o tym myśleć! :3

  20. radmen September 23, 2007 at 1:20 am #

    Riddle: dobrze wiedzieć, że to jest akordeon, zaraz poprawię ;-)
    kUtek: wybacz, ale ten komentarz z linkiem skasuję
    inina: najwyżej skopiesz im tyłki ;-)

  21. radmen September 23, 2007 at 1:20 am #

    Łukasz: przeczytaj sobie kurs na ferrante.pl :)

  22. Łukasz September 23, 2007 at 1:20 am #

    dzięki :)