Beiträge von Sempervivum
-
-
Zitat
Mir ist völlig unklar, welche beiden Werte ich nun miteinander vergleichen müsste.
$choosen ist ja offenbar die Antwort, für die sich der Benutzer entschieden hat. Und $row['trueanswer'] die richtige Antwort, die in der Datenbank hinterlegt ist. D. h. Du müsstest testen, ob sie gleich sind:
$choosen == $row['trueanswer']
liefert true, wenn sie übereinstimmen und false, wenn nicht.
Und das dann in die Antwort eintragen:
-
Zitat
Also einfach einen Eventlistener, der auf jeder Seite jeden klicke registriert?
Ja, könnte man so machen. Damit sich der Code nicht wiederholt, wenn es mehrere Seiten sind, kannst Du ihn ja auslagern.
-
Zitat
Man könnte noch per JS abfragen, ob der Tab aktiv ist
Das ist eine gute Idee, ich hatte mir nicht die Mühe gemacht, zu checken ob und wie es geht. Aber offenbar kein Problem:
-
Zitat
Geht das auch für wirklich jede Aktivität? Also z.b irgendwo hinklicken?
Natürlich, Du kannst für das ganze Dokument einen Eventlistener registrieren und ebenfalls eine Nachricht an den Server schicken. Wahrscheinlich nur, wenn nach dem letzten Klick oder Keypress eine gewisse Zeit verstrichen ist, sonst kann es bei wildem Klicken zu einer Flut von Nachrichten kommen.
-
Zunächst mal muss man festlegen, wann ein Benutzer als "noch aktiv" gelten soll:
a) Er hat eine Seite geöffnet, unabhängig davon ob er Aktivitäten ausführt. Dann kannst Du mit einem Heartbeat arbeiten, d. h. der Browser sendet zyklisch ein Lebenszeichen und beim Empfang wird das "last_seen" aktualisiert. Problem: Die Seite kann in einem nicht aktiven Tab noch offen sein und der Benutzer hat sie vergessen:
b) Der Benutzer führt irgend welche Aktivitäten aus. Dann kannst Du bei jeder Aktivität das "last_seen" aktualisieren. Kommt eine Aktivität nach Ablauf der Zeit, gilt er als ausgeloggt. Man kennt das ja, dass man eine Meldung bekommt der Form "Sie wurden aus Sicherheitsgründen ausgeloggt weil Sie mehr als xxx Minuten nicht aktiv waren."
-
Zitat
1. Wie müsste die Datenbank strukturiert sein, wie wird der richtige Eintrag gekennzeichnet?
Wenn es nur eine Spalte "trueanswer" gibt, ist es einfach: Du brauchst nur die ausgewählte Antwort mit der zu vergleichen, die vom Client bzw. Browser kommt, sind sie gleich, lieferst Du true zurück, wenn nicht false.
Zitat2. Wie schicke ich etwas zum Server? Bisher habe ich ja immer nur etwas geholt, habe also per JavaScript PHP-Dateien angesprochen, die Daten geholt haben.
Doch, auch bisher schon schickst Du etwas an der Server, und zwar als POST-Parameter z. B. hier, indem Du dem Objekt oneQuestion die ID mit append hinzu fügst und es im Body der Anfrage einträgt:
Codeconst oneQuestion = new FormData(); oneQuestion.append('id', i); fetch('animalgame2.php', { method: 'post', body: oneQuestion }).then // usw.Beim Holen der Info "Antwort ist richtig" brauchst Du jetzt nur noch die gewählte Antwort ebenfalls hinzu zu fügen:
Code// 3. Abfrage const trueAnswer = new FormData(); trueAnswer.append('id', i); trueAnswer.append('choosen', questions.answers[j]); fetch('animalgame3.php', { method: 'post', body: trueAnswer }).thenStatt der gewählten Antwort im Volltext könntest Du auch einfach nur den Index in der Datenbank eintragen und an den Server übertragen, das würde das Ganze etwas kompakter machen.
-
Du könntest es so lösen, dass Du nicht die richtige Antwort zurück lieferst sondern die ID und die gewählte Antwort an den Server schickst und dieser liefert dann nur ein boolean ob diese Antwort richtig war oder nicht.
-
Das sieht doch schon mal gut aus, kein Grund, dir Sorgen zu machen, dass es nicht korrekt ist.
Am besten das ganze, ohne das i = 1; in eine Funktion packen. Dann im HTML ein Button-Element einfügen und einen Eventlistener für "click" darauf registrieren. Darin kannst Du dann die Variable i erhöhen und durch Aufruf der Funktion die Frage und die Antworten holen und anzeigen.
Und bei der Definition von i besser ein let davor setzen: let i = 1:
-
Der Fehler, den ich jetzt gemacht habe, besteht darin, dass ich das click() vor dem Registrieren der Eventlistener gemacht habe, dann läuft es natürlich ins Leere. Und bei diesem Ansatz musst Du die Klasse "active" beim ersten Button wieder löschen.
Code
Alles anzeigenconst colls = document.getElementsByClassName('collapsible'); for (const coll of colls) { coll.addEventListener('click', function() { if (!this.classList.contains('active')) { collapseAllOpenContent(); } this.classList.toggle('active'); toggleContent(this.nextElementSibling); }); } colls[0].click();BTW, ich vergaß: Willkommen im Forum

-
OK, da lag ich offenbar daneben, weil die Elemente nicht über CSS sichtbar gemacht werden sondern über Javascript. Also neuer Versuch: Einfach einen Klick auf den ersten Button simulieren:
Code
Alles anzeigenconst colls = document.getElementsByClassName('collapsible'); colls[0].click(); for (const coll of colls) { coll.addEventListener('click', function() { if (!this.classList.contains('active')) { collapseAllOpenContent(); } this.classList.toggle('active'); toggleContent(this.nextElementSibling); }); }(ebenfalls ungetestet)
-
Ohne das groß getestet zu haben, scheint mir, dass das alles über die Klasse "active" bei den Buttons gesteuert wird. In dem Fall dürfte es ausreichend sein, bei dem betr. Button diese Klasse hinzu zu fügen:
-
-
Javascript beachtet Groß- und Kleinschreibung. getElementsByID musst Du so schreiben: getElementById.
Wenn der erste Text gleich offen sein soll, brauchst Du dem betr. Element nur die Klasse "active" zu geben.
Oder möchtest Du, dass er immer offen bleibt?
-
Gern geschehen, ich wünsche ebenfalls einen schönen Sonntag!
-
Wenn man das vorige Element schließen will, wird es leider ein wenig komplizierter. Ich habe das folgende Javascript kommentiert, damit Du verstehst, was sich abspielt:
Code
Alles anzeigen<script> const buttons = document.getElementsByClassName('flexbox-button2'), contents = document.getElementsByClassName('flexbox-content'); // Weil sich der aktive bzw. offene Content von Klick zu Klick ändert // müssen wir das aktive Element innerhalb des Eventlisteners ermitteln. // contentActive = document.querySelector('.flexbox-content.active') for (let i = 0; i < buttons.length; i++) { buttons[i].addEventListener('click', function () { // Jetzt das aktive Element ermitteln: const contentActive = document.querySelector('.flexbox-content.active'); // Es kann sein, dass // 1. das aktive Element das gerade geklickte ist // 2. es gerade kein aktives Element gibt // Dies müssen wir prüfen bevor wir das Element schließen: if (contentActive && contentActive != contents[i]) { // Jetzt das aktive Element schließen: contentActive.classList.remove('active'); } // Jetzt können wir die Sichtbarkeit des aktuellen // Elements umschalten: contents[i].classList.toggle('active') }); } </script> -
Zitat
Wie genau kann ich denn den vorherig angeklickten Button mit diesem Code ansprechen?
Das kannst Du, indem Du querySelector verwendest und die Klasse "active" angibst:
const contentActive = document.querySelector('.flexbox-content.active');
-
Da gibt es jetzt zwei Probleme:
1. Im HTML und CSS verwendest Du für die Buttons die Klasse "flexbox-button2", im Javascript jedoch "flexbox-button", d. h. Du musst das Javascript so ändern:
Code<script> const buttons = document.getElementsByClassName('flexbox-button2'), contents = document.getElementsByClassName('flexbox-content'); for (let i = 0; i < buttons.length; i++) { buttons[i].addEventListener('click', function () { contents[i].classList.toggle('active') }); } </script>Und im CSS musst Du die den Content zunächst unsichtbar machen, indem Du die Höhe auf 0 setzt:
-
Danke, so wird das Ganze klar. Ohne es ein wenig umzuorganisieren, wird sich dein gewünschtes Layout wohl nicht realisieren lassen. Also links ein Container mit den Buttons und rechts einer mit den Inhalten. Und dann muss man eine Beziehung zwischen den Buttons links und den Inhalten rechts herstellen. Ich dachte zunächst daran, das mit einem data-Attribut bei den Buttons zu machen, aber mit diesem HTML und Javascript dürfte das gar nicht notwendig sein:
Code
Alles anzeigen<section class="left-buttons"> <!-- hier die Buttons mit der Klasse "flexbox-button" untereinander --> </section> <section class="right-content"> <!-- hier die Content-Container mit der Klasse flexbox-content untereinander --> </section> <script> const buttons = document.getElementsByClassName('flexbox-button'), contents = document.getElementsByClassName('flexbox-content'); for (let i = 0; i < buttons.length; i++) { buttons[i].addEventListener('click', function () { contents[i].classList.toggle('active') }); } </script>(ungetestet)
Das HTML musst Du selber noch vervollständigen.
-
Leider kann ich aus dem HTML und CSS nicht erkennen, wie dieses Accordion funktioniert. Weder finde ich Check- oder Radiobuttons noch ein Javascript, das es macht. Irgend wie mit diesem kit.fontawesome? Oder der CSS-Datei, die Du einbindest? Kannst Du das erklären?