• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Resetowanie strony

Object Storage Arubacloud
0 głosów
320 wizyt
pytanie zadane 20 lipca 2019 w JavaScript przez Allen Obywatel (1,010 p.)
edycja 20 lipca 2019 przez Allen
var cards=["ciri.png", "geralt.png", "jaskier.png", "jaskier.png", "iorweth.png", "triss.png", "geralt.png", "yen.png", "ciri.png", "triss.png", "yen.png", "iorweth.png"];
//console.log(cards);

var c0=document.getElementById('c0');
var c1=document.getElementById('c1');
var c2=document.getElementById('c2');
var c3=document.getElementById('c3');

var c4=document.getElementById('c4');
var c5=document.getElementById('c5');
var c6=document.getElementById('c6');
var c7=document.getElementById('c7');

var c8=document.getElementById('c8');
var c9=document.getElementById('c9');
var c10=document.getElementById('c10');
var c11=document.getElementById('c11');

c0.addEventListener("click", function(){revealCard(0);});
c1.addEventListener("click", function(){revealCard(1);});
c2.addEventListener("click", function(){revealCard(2);});
c3.addEventListener("click", function(){revealCard(3);});

c4.addEventListener("click", function(){revealCard(4);});
c5.addEventListener("click", function(){revealCard(5);});
c6.addEventListener("click", function(){revealCard(6);});
c7.addEventListener("click", function(){revealCard(7);});

c8.addEventListener("click", function(){revealCard(8);});
c9.addEventListener("click", function(){revealCard(9);});
c10.addEventListener("click", function(){revealCard(10);});
c11.addEventListener("click", function(){revealCard(11);});

var again=document.getElementById('again');
again.addEventListener("click", function(){window.location.reload(true);});

//$('again').on('click', function() {window.location.reload(true())};

var oneVisible=false;
var turnCounter=0;
var visible_nr;
var lock=false;
var pairsLeft=6;

function revealCard(nr)
{
    var opacityValue=$('#c'+nr).css('opacity');
    if(opacityValue!=0 && lock==false)
    {
        lock=true;
        var obraz="url(img/"+cards[nr]+")";

        $('#c'+nr).css('background-image', obraz);
        $('#c'+nr).addClass('cardA');
        $('#c'+nr).removeClass('card');

        //w ten sam sposób można dodać zmianę borderu oraz brightness'essu jak coś
        //addClass dodaję klasę, ale nie zastępuję klas dodanych wcześniej. O poprawnym działaniu decyduje koleność zapisu w css.

        if(oneVisible==false)
        {
            oneVisible=true;
            visible_nr=nr;
            lock=false;
        }
        else
        {
            if(cards[visible_nr]==cards[nr])
            {
                setTimeout(function(){hide2Cards(nr, visible_nr)},750);
            }
            else
            {
                setTimeout(function(){restore2Cards(nr, visible_nr)},1000);
            }

            turnCounter++;
            $('.score').html('Turn counter: '+turnCounter);
            oneVisible=false;
        }
    }
}

function hide2Cards(nr1, nr2)
{
    $('#c'+nr1).css('opacity','0');
    $('#c'+nr2).css('opacity','0');
    
    pairsLeft--;
    
    if(pairsLeft==0)
        {
            $('.board').html('<h1> You win!<br>Done in '+turnCounter+' turns</h1><br>');
            $('#again').css('dislpay', 'block');
        }
    
    lock=false;
}

function restore2Cards(nr1, nr2)
{
    $('#c'+nr1).css('background-image', 'url(img/karta.png)');
    $('#c'+nr1).addClass('card');
    $('#c'+nr1).removeClass('cardA');
    
    $('#c'+nr2).css('background-image', 'url(img/karta.png)');
    $('#c'+nr2).addClass('card');
    $('#c'+nr2).removeClass('cardA');
    
    lock=false;
}
body
{
    background-color: #26282E;
    color: #209781;
    font-size: 28px;
    font-family: 'Lobster', sans-serif;
}

a:link {color: #209781; text-decoration: none;}
a:visited {color: #209781;}
a:active {color: #209781;}
a:hover {color: #E9B64A;}

h1
{
    font-size: 64px;
    font-weight: 400;
    text-align: center;
    letter-spacing: 5px;
    margin-top: 20px;
    margin-bottom: 0px;
}

p
{
    text-align: center;
    margin-top: 5px;
    margin-bottom: 25px;
    letter-spacing: 2px;
}

.board
{
    width: 600px;
    margin-left: auto;
    margin-right: auto;
    text-align: center;
}

.cardA
{
    width: 125px;
    height: 125px;
    display: inline-block;
    margin: 3px;
    background-image: url("img/karta.png");
    border: 4px solid #e9b64a;
    border-radius: 4px;
    cursor: default;
    filter: brightness(100%);
    transform: all .3s ease-in-out;
}

.card
{
    width: 125px;
    height: 125px;
    display: inline-block;
    margin: 3px;
    background-image: url("img/karta.png");
    border: 4px solid #51c8b2;
    border-radius: 4px;
    cursor: pointer;
    filter: brightness(70%);
    transform: all .3s ease-in-out;
}

.card:hover
{
    border: 4px solid #e9b64a;
    filter: brightness(100%);
}

.score
{
    margin-top: 5px;
    letter-spacing: 2px;
}

#again
{
    width: 140px;
    height: 90px;
    padding: 5px;
    margin: auto; /*jak ustawić mrgin left i right na auto 1 linią*/
    display: none;
    letter-spacing: 5px;
    color: #209781;
    text-align: center;
    font-size: 64px;
}

#again:hover
{
    cursor: pointer;
}


<html>
<head lang="pl">
    <meta charset="UTF-8">
    <title>Memory Test</title>
    <link rel="stylesheet" href="main.css">
    <link href="https://fonts.googleapis.com/css?family=Lobster&amp;subset=latin-ext" rel="stylesheet">
    <!--<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>-->
</head>
<body>
    <header>
        <h1>Memory Test</h1>
        <p>Let's play a game</p>
    </header>
    
    <main>
        <article>
           <div class="board">
               <div class="card" id="c0"></div>
               <div class="card" id="c1"></div>
               <div class="card" id="c2"></div>
               <div class="card" id="c3"></div>
               
               <div class="card" id="c4"></div>
               <div class="card" id="c5"></div>
               <div class="card" id="c6"></div>
               <div class="card" id="c7"></div>
               
               <div class="card" id="c8"></div>
               <div class="card" id="c9"></div>
               <div class="card" id="c10"></div>
               <div class="card" id="c11"></div>
               
               <div class="score">Turn counter: 0</div>

               <button type="submit" id="again">Play again!</button>
           </div>
        </article>
    </main>
    <script src="jquery-3.2.1.min.js" type="text/javascript"></script>
    <script src="memory.js" type="text/javascript"></script>
</body>
</html>

Kod odnosi się do gry M. Zelenta z 5 odc. kursu javascript. Chcę, aby po zakryciu wszystkich kart na ekranie pojawił się przycisk, dzięki któremu można by odświeżyć stronę i nie mam pojęcie gdzie popełniam błąd. Proszę o pomoc.

 

2 odpowiedzi

0 głosów
odpowiedź 20 lipca 2019 przez niezalogowany
Jeżeli to ma być ten przycisk zakomentowany to dodałeś klasę again a obiekt again tworzysz przez document.getElementById czyli nie ma takiego elementu. Zmień class na id lub używaj document.getElementByClassName.
komentarz 20 lipca 2019 przez Allen Obywatel (1,010 p.)
Przepraszam skopiowałem kod przed zmianą. Poprawiłem już to i nadal nie działa, stąd pytanie na forum.
komentarz 20 lipca 2019 przez ScriptyChris Mędrzec (190,190 p.)

Jeśli kod wstawiony w pytaniu nie jest aktualny, to uaktualnij go proszę poprzez edycję posta.

komentarz 20 lipca 2019 przez Allen Obywatel (1,010 p.)
Już to zrobiłem
komentarz 20 lipca 2019 przez ScriptyChris Mędrzec (190,190 p.)
edycja 20 lipca 2019 przez ScriptyChris

Po czym wnioskujesz, że przycisk nie działa?

Przycisk sam w sobie działa, jeśli "wymuszę" jego pokazanie w CSS bez konieczności przechodzenia gry. Jak rozumiem problem w tym, że nie działa jego pokazywanie?

komentarz 20 lipca 2019 przez Allen Obywatel (1,010 p.)
Nie wyświetla się po odgadnięciu wszystkich kart.
komentarz 20 lipca 2019 przez ScriptyChris Mędrzec (190,190 p.)

Sprawdź, czy to nie wina literówki w 'dislpay':

$('#again').css('dislpay', 'block');

 

komentarz 20 lipca 2019 przez Allen Obywatel (1,010 p.)
Poprawiłem literówkę, lecz nic to nie dało i przycisk dalej się nie wyświetla.
0 głosów
odpowiedź 20 lipca 2019 przez ScriptyChris Mędrzec (190,190 p.)

Pierwszy problem, to literówka, którą wskazałem w komentarzu.

Drugi problem jest taki, że zmieniasz zawartość HTML całego diva .board, w którym jest przycisk - czyli właściwie go usuwasz z DOM, a dopiero potem próbujesz go pokazać. Więc, albo przenieś przycisk poza <div class="board">, albo zamiast czyścić cały HTML planszy, po prostu ją ukryj, a w osobnym elemencie trzymaj komunikat o końcu gry i go pokaż razem z przyciskiem. Natomiast po wciśnięciu odśwież stronę lub (lepsze rozwiązanie) zresetuj stan gry.

komentarz 20 lipca 2019 przez Allen Obywatel (1,010 p.)
Dziękuję za odpowiedź. Dopiero zaczynam naukę i nie wiem nawet jak zresetować stan gry nie odświeżając strony.
komentarz 20 lipca 2019 przez ScriptyChris Mędrzec (190,190 p.)

Przywróć początkowe wartości zmiennym, które odpowiadają za sterowanie programem oraz nadaj elementom DOM taki stan (widoczność, kolory itp.), jaki mają na początku gry. Dobrze by było, gdybyś opakował taki kod w funkcję o nazwie np. init i wołał ją zarówno na początku programu jak i przy resetowaniu - ona odpowiadała by za ustawianie początkowych (domyślnych) wartości zmiennym i elementom DOM.

komentarz 21 lipca 2019 przez Allen Obywatel (1,010 p.)
Rozumiem, ale dlaczego takie rozwiązanie będzie lepsze od zwykłego odświeżenia strony?
komentarz 21 lipca 2019 przez ScriptyChris Mędrzec (190,190 p.)
Bo nie ma sensu wczytywać od nowa HTMLa, CSSa, JSa i pozostałych assetów (jak np. obrazki), skoro szybciej i bez łączenia się z serwerem można po prostu zresetować stan aplikacji.
komentarz 21 lipca 2019 przez Allen Obywatel (1,010 p.)

Dziękuję, mam jeszcze jedno pytanie. Chcę zablokować możliwość kliknięcia w odkrytą kartę i w tym celu dodałem 4 ostatnie linijki w if'ie:

if(oneVisible==false)
        {
            oneVisible=true;
            visible_nr=nr;
            lock=false;
            document.getElementById('#c'+nr).setAttribute("onclick", ";");
            var c_ran=document.getElementById('#c'+nr);
            c_ran.removeEventListener("click", function(){revealCard();});
            return listener();
        }

Dowiedziałem się że ten sposób nie zadziała, ponieważ listenery nie są w żaden sposób powiązane. Rozwiązaniem miało by być przypisanie funkcji revealCard do jakiejś zmiennej np. var handler=function revealCad() . Problem polega na tym że nie wiem jak w takie sytuacji przesłać argument (kolejne liczby od 0 do 11) do funkcji revealCard. Proszę o pomoc.

komentarz 21 lipca 2019 przez ScriptyChris Mędrzec (190,190 p.)

Najprościej to wstaw do listenera if, który pozwoli na wywołanie funkcji revealCard, albo nie. Nie rozumiem po co ustawiasz atrybut onclick na znak średnika i czym jest funkcja listener, której wynik wywołania zwracasz. Użycie removeEventListener wymaga podania tej samej referencji do funkcji, która została przekazana do addEventListener - anonimowa funkcja nie zadziała.

nie wiem jak w takie sytuacji przesłać argument (kolejne liczby od 0 do 11) do funkcji revealCard

Skoro w innych przypadkach przekazujesz tam numer karty - tak ja interpretuję Twój kod:

c0.addEventListener("click", function(){revealCard(0);});

, to przekaż zmienną nr (jeśli ona przechowuje prawidłowy numer karty).

komentarz 21 lipca 2019 przez Allen Obywatel (1,010 p.)

Ok. Js uczę się dosłownie od kilku dni i jak dotąd samodzielnie nie radzę sobie z niczym. 

var cards_list=["ciri.png", "geralt.png", "jaskier.png", "jaskier.png", "iorweth.png", "triss.png", "geralt.png", "yen.png", "ciri.png", "triss.png", "yen.png", "iorweth.png"];
var cards=new Array();

for(i=12; i>0; i--)   //0.99*12=11.88
{
    var rand_id=Math.floor(Math.random*i);
    cards.push(cards_list[rand_id]);
}

var cards_list=["ciri.png", "geralt.png", "jaskier.png", "jaskier.png", "iorweth.png", "triss.png", "geralt.png", "yen.png", "ciri.png", "triss.png", "yen.png", "iorweth.png"];
//var cards=[];

for(i=12; i>0; i--)
{
    var rand_id=Math.floor(Math.random*i);
    Array.prototype.push.apply(cards_list[rand_id], cards);
}

Zamieściłem 2 sposoby losowego zapisania układu kart do tablicy cards. Żaden nie działa i również nie mam pojęcia, gdzie znajduje się błąd.

komentarz 21 lipca 2019 przez ScriptyChris Mędrzec (190,190 p.)
Math.random*i

Math.random to funkcja, zmienna i jest liczbą. Operator mnożenia zwraca w tym przypadku wartość NaN, ponieważ funkcja nie jest typu liczbowego. A, że w tablicy cards_list nie ma takiego property, to zwrócone zostanie undefined i wrzucone do tablicy cards. Zapomniałeś więc wywołać tą funkcję przy mnożeniu, czyli:

var rand_id=Math.floor(Math.random() * i);

, bo aktualnie tablica cards zawiera 12 wartości undefined.

Drugi sposób (oprócz powtórzonego błędu z brakiem wywołania Math.random) powoduje błąd, ponieważ metoda apply jako pierwszy parametr przyjmuje obiekt, który będzie traktować jak "wskaźnik" this, a Ty przekazujesz tam ponownie undefined. Poza tym, drugim parametrem powinna być tablica. Jeśli już, to lepiej pasuje call:

Array.prototype.push.call(cards, cards_list[rand_id]);

 

komentarz 21 lipca 2019 przez Allen Obywatel (1,010 p.)
Bardzo dziękuję za wytłumaczenie wszystkiego.

Pozdrawiam.

Podobne pytania

0 głosów
2 odpowiedzi 535 wizyt
pytanie zadane 4 sierpnia 2016 w JavaScript przez Adam Jakś Dyskutant (8,940 p.)
0 głosów
0 odpowiedzi 1,372 wizyt
pytanie zadane 18 lipca 2016 w JavaScript przez Alterwar Dyskutant (7,650 p.)
0 głosów
3 odpowiedzi 226 wizyt
pytanie zadane 26 kwietnia 2016 w Java przez shimizu Obywatel (1,650 p.)

92,570 zapytań

141,422 odpowiedzi

319,643 komentarzy

61,958 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...