Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [AJAX]zakładki tab bez przeładowywania i ich zapamiętanie po odświeżeniu
Forum PHP.pl > Forum > Przedszkole
casperii
Witam,
Chciałbym to zmodyfikować w ten sposób aby, po wybraniu taba i odświeżeniu strony pamiętało który tab był wczytany. Zrobiłem póki co tak:
mam kod:
  1. $(function (){
  2. $('[data-tab]').on('click', function (e){
  3. var that = $(this);
  4. var parent = that.parent().parent().parent();
  5. that
  6. .addClass('active')
  7. .siblings('[data-tab]')
  8. .removeClass('active');
  9. $('[data-content]',parent)
  10. .removeClass('active')
  11. .siblings('[data-content=' + that.data('tab') + ']')
  12. .addClass('active');
  13. e.preventDefault();
  14. });
  15. });
  16. <div style="margin-bottom:10px;" data-tab="#1" class="tab active">link1</div>
  17. <div style="margin-bottom:10px;" data-tab="#2" class="tab">link2</div>
  18.  
  19. <div data-content="#1" class="klasa active">zawartość</div>
  20. <div data-content="#1" class="klasa">zawartość drugiego taba</div>


Rozumiem, że teraz powinienem zrobić coś na styl :

select: function(event, ui) {
window.location.replace(ui.tab.hash);
}

Ale za cholerę nie mogę sobie z tym poradzić.
nospor
Co rozumiesz przez odswiezenie strony? Bo kod co podales powinien działać przy normalnym odswiezeniu strony
casperii
Cytat(nospor @ 21.05.2015, 14:17:09 ) *
Co rozumiesz przez odswiezenie strony? Bo kod co podales powinien działać przy normalnym odswiezeniu strony


A co mam rozumieć, poprzez normale odświeżenie strony? closedeyes.gif
Chcę by po wybraniu któregoś linka załadowało taba (tak do tej pory jest) oraz zapamiętało wybór. Ten wybór musi być zapamiętany nawet wtedy gdy user wciśnie "odśwież" lub F5. Także potrzebował by to wtedy gdybym chciał requestem odświeżyć stronę.
nospor
Cytat
A co mam rozumieć, poprzez normale odświeżenie strony?
Ludzie roznie rozne rzeczy rozumieją a szczegolnie ci "początkujacy". Podales kod, ktory powinien działać, dlatego sie pytam co rozumiesz przez przeladowanie, bo rownie dobrze mogles klikac na LINK i mowic, ze odswiezyles strone....

Jesli wiec uzywasz odswiezenia, czyli F5, ctrl+R czy czegos podobnego to kod powinien działać. Jesli nie działa to:
1) Jaki jest dokładnie adres strony, gdy wchodzisz na nią pierwszy raz?
2) Jaki jest dokladnie adres strony, gdy klikasz na którąś z zakładek? Powinien się zmienic.
casperii
Źle mnie zrozumiałeś. Pierwszy kod dałem na wzór, gdyż on działa w 100%. Drugi kod jest już mój i chciałbym tam wstawić:

  1. select: function(event, ui) {
  2. window.location.replace(ui.tab.hash);
  3. }


I teraz nie za bardzo wiem, jak to połączyć z tym moim:

  1. $(function (){
  2. $('[data-tab]').on('click', function (e){
  3. var that = $(this);
  4. var parent = that.parent().parent().parent();
  5. that
  6. .addClass('active')
  7. .siblings('[data-tab]')
  8. .removeClass('active');
  9. $('[data-content]',parent)
  10. .removeClass('active')
  11. .siblings('[data-content=' + that.data('tab') + ']')
  12. .addClass('active');
  13. e.preventDefault();
  14. });
  15. });
nospor
Faktycznie, źle Cię zrozumiałem.
Samo ustawienie hasha w url nic nie da. Musisz jeszcze w js go obsluzyc i na jego podstawie ustawić swoją aktywną zakładkę.
casperii
Gdybym jeszcze wiedział jak się za to zabrać. Może umiałbyś mi pomóc?
nospor
Zajrzyj do google, ja pobrac hash w js z url. Majac hash, ustawiasz swoją aktywną zakładkę tak jak to robisz teraz
casperii
Cytat(nospor @ 21.05.2015, 14:38:14 ) *
Zajrzyj do google, ja pobrac hash w js z url. Majac hash, ustawiasz swoją aktywną zakładkę tak jak to robisz teraz


Dobra mam coś takiego:

var url = location.pathname + that.data('tab'); //pobiera mi linka z kotwicą
var hash = url.substring(url.indexOf('#')); //pobiera samą kotwice.

Ale dalej nie wiem jak zrobić mam to.
nospor
Majac hasha, robisz aktywny ten div, ktory ma tego hasha. Robiles juz aktywnosc danego diva w kodzie w pierwszym poscie.
casperii
Cytat(nospor @ 21.05.2015, 15:12:37 ) *
Majac hasha, robisz aktywny ten div, ktory ma tego hasha. Robiles juz aktywnosc danego diva w kodzie w pierwszym poscie.



No dobra ma coś takiego :
Kod
<script>
$(function (){
    $('[data-tab]').on('click', function (e){
        var that = $(this);
        var parent = that.parent().parent().parent();
        that
        .addClass('active')
        .siblings('[data-tab]')
        .removeClass('active');
        $('[data-content]',parent)
        .removeClass('active')
        .siblings('[data-content=' + that.data('tab') + ']')
        .addClass('active');
        e.preventDefault();
        
        var url = location.pathname + that.data('tab');
        var hash = url.substring(url.indexOf('#'));
        window.location.replace(url); // // to mi teraz dodaje kotwice do linka. Ale po odświeżeniu strony wraca na tab active, czyli na ten pierwszy link .

        
        //alert('zobacz' + url + 'lub' + hash);
    });
});
</script>


Nie zapamiętuje tab active po odświeżeniu. Kotwice już są w linku.
nospor
Ty nie masz tego kodu
var hash = url.substring(url.indexOf('#'));
dodawac do onclicka, tylko ty masz ten kod odpalic po zaladowaniu strony i na podstawie hash aktywowac odpowiedniego diva. Piszac, ze kod do aktywacji miales juz podobny wczesniej, nie znaczylo ze masz tam dowalic swoj kod nowy. To znaczylo, ze kod stamtad, masz wykorzystac w zaznaczaniu zakladki z urla
Comandeer
Nie wiem czy to coś pomoże czy nie, ale podobny mechanizm mam zrobiony u siebie (nie jest to co prawda jQuery UI, ale metoda działania identyczna): http://tutorials.comandeer.pl/#html vs http://tutorials.comandeer.pl
Comandeer
Wyszedłbym od implementacji no-js, bo napisanie takiej jest banalnie proste:
Kod
<!DOCTYPE html>
    <html lang="pl" dir="ltr" class="no-js">
        <head>
            <meta charset="UTF-8">
            <script>(function(H){H.className=H.className.replace(/\bno-js\b/,'js')})(document.documentElement)</script>
            <title>Ehhhh</title>
            <style>
            .menu .tab
            {
                border: 1px #000 solid;
                border-radius: 20px;
            }
            .menu .tab.active, .menu .tab:hover
            {
                background: #bbb;
            }
            
            .tabs .tab
            {
                display: none;
            }

            .tabs .tab:target, .js .tabs .tab.active
            {
                display: block;
            }
            </style>
        </head>
        <body>
            <ul class="menu">
                <li><a href="#tab1" class="tab active">tab1</a></li>
                <li><a href="#tab2" class="tab">tab2</a></li>
            </ul>
            
            <div class="tabs">
                <div id="tab1" class="tab">zawartość</div>
                <div id="tab2" class="tab">zawartość drugiego taba</div>
            </div>
        </body>
    </html>


Teraz zastanówmy się co dokładnie potrzebujemy od JS?
  • Reagowania na zmianę w pasku adresu i zaznaczenia odpowiedniego linku w menu
  • Jeśli nie ma nic w adresie, to zaznaczenie i wyświetlenie domyślnego tabu

Tyle - całą resztę robi za nas CSS.

Jak zatem będzie wyglądać tego typu funkcja w JS (jQuery)?
Kod
(function()
{
    var changeTab = function(sel) //funkcja zmieniająca taba
    {
        var $menu = $('.menu') //bierzemy nawigację tabów
        ,$link = $menu.find('.tab[href=' + sel + ']') //pobieramy odpowiedni link
        ,$tabs = $('.tabs') //pobieramy kontener tabów
        ,$tab = $(sel); //pobieramy odpowiedni tab

        $menu.find('a').removeClass('active'); //usuwamy klasę ze wszystkich elementów menu
        $link.addClass('active'); //ustawiamy tę klasę odpowiedniemu linkowi

        //powtarzamy to dla taba
        $tabs.find('.tab').removeClass('active');
        $tab.addClass('active');
    }
    ,handleHash = function() //funkcja obsługująca hash
    {
        //operator trójkowy sprawdza czy coś mamy w adresie - jeśli tak, przekazuje to funkcji changeTab; jeśli nie - przekazuje [id] 1. tabu z # na początku
        changeTab(location.hash ? location.hash : '#' + $('.tabs .tab').first().attr('id'));
    };

    //wywołujemy handleHash na starcie strony
    handleHash();
    //i przy zmianie hashu w adresie
    $(window).on('hashchange', handleHash)
}());

Całość zatem wygląda następująco:
Kod
<!DOCTYPE html>
    <html lang="pl" dir="ltr" class="no-js">
        <head>
            <meta charset="UTF-8">
            <script>(function(H){H.className=H.className.replace(/\bno-js\b/,'js')})(document.documentElement)</script>
            <title>Ehhhh</title>
            <style>
            .menu .tab
            {
                border: 1px #000 solid;
                border-radius: 20px;
            }
            .menu .tab.active, .menu .tab:hover
            {
                background: #bbb;
            }
            
            .tabs .tab
            {
                display: none;
            }

            .no-js .tabs .tab:target, .js .tabs .tab.active
            {
                display: block;
            }
            </style>
        </head>
        <body>
            <ul class="menu">
                <li><a href="#tab1" class="tab">tab1</a></li>
                <li><a href="#tab2" class="tab">tab2</a></li>
            </ul>
            
            <div class="tabs">
                <div id="tab1" class="tab">zawartość</div>
                <div id="tab2" class="tab">zawartość drugiego taba</div>
            </div>

            <script src="http://code.jquery.com/jquery.min.js"></script>
            <script>(function()
            {
                var changeTab = function(sel) //funkcja zmieniająca taba
                {
                    var $menu = $('.menu') //bierzemy nawigację tabów
                    ,$link = $menu.find('.tab[href=' + sel + ']') //pobieramy odpowiedni link
                    ,$tabs = $('.tabs') //pobieramy kontener tabów
                    ,$tab = $(sel); //pobieramy odpowiedni tab

                    $menu.find('a').removeClass('active'); //usuwamy klasę ze wszystkich elementów menu
                    $link.addClass('active'); //ustawiamy tę klasę odpowiedniemu linkowi

                    //powtarzamy to dla taba
                    $tabs.find('.tab').removeClass('active');
                    $tab.addClass('active');
                }
                ,handleHash = function() //funkcja obsługująca hash
                {
                    //operator trójkowy sprawdza czy coś mamy w adresie - jeśli tak, przekazuje to funkcji changeTab; jeśli nie - przekazuje [id] 1. tabu z # na początku
                    changeTab(location.hash ? location.hash : '#' + $('.tabs .tab').first().attr('id'));
                };

                //wywołujemy handleHash na starcie strony
                handleHash();
                //i przy zmianie hashu w adresie
                $(window).on('hashchange', handleHash)
            }());
            </script>
        </body>
    </html>

Voilla! Prosta implementacja tabów gotowa wink.gif
casperii
Sporo się napisałeś @Comandeer ale w dalszym ciągu to nie jest to o co mi chodzi, ponieważ takie coś to ja też mam testowo ale tam dodaje ui , pozatym linki są w li a href.
A ja mam to w divach to po pierwsze , po drugie musiałbym cały kod przerabiać.


Link już jest tworzony w przeglądarce tzw. zrobione jest już kotwiczenie, po odświeżeniu pamięta kotwice, ale nie pamięta na jakim był class tab active i wraca na pierwszy tab.
Comandeer
Jak dla mnie to jest niepotrzebne kombinowanie… Link to link, nie div. Polecam spróbować to obsłużyć np. klawiaturą.

Co do problemu -
Kod
//wywołujemy handleHash na starcie strony
handleHash();

O to się głównie rozchodzi.
W twoim wypadku byłoby to coś typu
Kod
$('[data-tab=' + hashZAdresu + ']).click();

czyli sztuczne wywołanie kliku na danym linku - powinno działać
casperii
Cytat(Comandeer @ 21.05.2015, 19:31:50 ) *
Jak dla mnie to jest niepotrzebne kombinowanie… Link to link, nie div. Polecam spróbować to obsłużyć np. klawiaturą.

Co do problemu -
Kod
//wywołujemy handleHash na starcie strony
handleHash();

O to się głównie rozchodzi.
W twoim wypadku byłoby to coś typu
Kod
$('[data-tab=' + hashZAdresu + ']).click();

czyli sztuczne wywołanie kliku na danym linku - powinno działać


Ale mi działa klikanie na pseudo linki czyli te DIVY. Nie działa mi jak już pisałem zapamiętywanie otwartego tab i class active.
Comandeer
Ok. Ale zamysł jest taki - jeśli Twój kod zmienia adres w pasku przeglądarki, to przy starcie strony wystarczy wywołać klik na "linku", który jest w adresie. Tym sposobem powinien zostać zaznaczony odpowiedni div
casperii
Cytat(Comandeer @ 21.05.2015, 20:11:59 ) *
Ok. Ale zamysł jest taki - jeśli Twój kod zmienia adres w pasku przeglądarki, to przy starcie strony wystarczy wywołać klik na "linku", który jest w adresie. Tym sposobem powinien zostać zaznaczony odpowiedni div


@Comandeer no dobra nawet jak zamienie to:

Kod
$('[data-tab]').on('click', function (e){


na to:

Kod
$('[data-tab=' + hash + ']').on('click', function (e){


to przecież i tak hash się generuje dopiero z chwilą akcji click. No dobra myślę, sobie stworzę na sztywno z chwilą wczytania strony niech var hash ma = 1. Ale to też nie działa.
Comandeer
Ale czemu nie pobierzesz go z adresu?
casperii
@Comandeer no dobra pobieram sobie adres strony tak ?

Kod
var adr=window.location.href;
alert('pokazuje' + adr);


i co później?
jak wstawie zamiast

Kod
$('[data-tab]').on('click', function (e){

takie coś to w ogóle nie przeładowuje
Kod
$(adr).on('click', function (e){


Kod
$(function (){
    $('[data-tab]').on('click', function (e){
        that
        .addClass('active')
        .siblings('[data-tab]')
        .removeClass('active');
        $('[data-content]',parent)
        .removeClass('active')
        .siblings('[data-content=' + that.data('tab') + ']')
        .addClass('active');
        e.preventDefault();
    });
});
Comandeer
Eh, ja o A, a Ty o B… wink.gif
elem.click() vs elem.on('click', function() {[…]}) - widać różnicę?
Kod
if(location.hash)
        $('[data-tab=' + location.hash + ']').click();

Łap cały kod JS:
Kod
$(function (){
    $('[data-tab]').on('click', function (e){
        var that = $(this);
        var parent = that.parent().parent().parent();
        var url = location.pathname + that.data('tab');
        var hash = url.substring(url.indexOf('#'));
        window.location.replace(url);
        that
        .addClass('active')
        .siblings('[data-tab]')
        .removeClass('active');
        $('[data-content]',parent)
        .removeClass('active')
        .siblings('[data-content=' + that.data('tab') + ']')
        .addClass('active');
        e.preventDefault();
        //alert('zobacz' + url);
    });

    if(location.hash)
        $('[data-tab=' + location.hash + ']').click();
});
casperii
Dziękuje Dziękuje Dziękuje. Ale ja durny cep. ohno-smiley.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.