#1 Spoiler mit Cookies von Wolfgang 05.05.2011 02:11

avatar

Hallo Florian,
ich habe hier ein Script, bei dem der Spoilerzustand gespeichert werden soll. Funktioniert aber nicht richtig.
Läßt sich da etwas machen?


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
 
<html>
<head>
<title>Spoiler</title>
 
<script type="text/javascript">

var menuClicked = false;
if ( getCookie( 'menuOpener' ) == 0 ) {
menuClicked = true;
}

function menuShow() {
if ( menuClicked ) {
menuClicked = false;
 
document.cookie = 'menuOpener=1';
document.getElementById( 'menuContent1' ).style.display='none';
} else {
menuClicked = true;
 
document.cookie = 'menuOpener=0';
document.getElementById( 'menuContent1' ).style.display='block';
}
}
 
</script>
</head>
 
<body>
<p class="spoiler">
<b>Spoiler</b>
<a href="#" onClick="javascript:menuShow()">show</a><span id="menuContent1" style="display:none">das ist geheim.</span></p>
</body>
</html>
 

 





Bis dann und besten Dank im Voraus
Wolfgang

#2 RE: Spoiler mit Cookies von florian-zier 06.05.2011 14:29

avatar

Hallo Wolfgang,
der Fehler leigt wahrscheinlich nur an der Cookie-Speicherung, denn Firebug bleibt (zurecht) an der Funktion getCookie() mit einem Fehler hängen.
Die Funktion ist schlicht und einfach noch nicht vorhanden, da sie nicht bereits in JavaScript vordefiniert ist.

Ich schlage vor, du suchst dir über Google die Funktionen für's Cookie Setzen und Auslesen heraus.
Damit sparst du dir die Arbeit, manuell eines zu setzen (und mit document.cookie zu arbeiten) und musst nur mittels getCookie() bzw setCookie() Namen und Wert angeben.
Ein Beispiel aus den ersten paar Suchergebnissen und ein anderes Beispiel.

Einige Seiten bieten noch eine Funktion deleteCookie() an, andere eben nicht, da mittels setCookie und einer Datumsangabe in der Vergangenheit ein Cookie gelöscht werden kann.
Manchmal heißen die Funktionen auch get_cookie() o.ä., dass muss man eben beim Aufruf im eigenen Skript dann beachten.
Ob die Skripte wirklich gut funktionieren, findet man leider meistens nur durchs testen heraus.
Mit den Firefox-Addons Firebug und Firecookie kannst du überprüfen, welche Cookies gesetzt sind und diese auch wieder löschen, um zu sehen ob sie korrekt gesetzt werden. (auch Werte können angepasst werden)


Sollte es funktionieren das Cookie auszulesen, dann musst du nur noch einmal die Funktion menuShow() beim Onload ausführen, sofern das Cookie den Geöffnet-Status übermittelt.

#3 RE: Spoiler mit Cookies von Wolfgang 06.05.2011 17:35

avatar

Danke für die schnelle Anwort.
Mal sehen, was sich machen läßt.

Viele Grüße Wolfgang

#4 RE: Spoiler mit Cookies von florian-zier 16.05.2011 18:47

avatar

Hallo Wolfgang,
gute Nachrichten!

Ich habe inzwischen einen lauffähigen Code für die automatische Spoiler-Anzeige (nur HPM-Spoiler) erstellen können.
Getestet habe ich das Skript in der neuesten IE- und Firefox-Version, sowie Opera und Google Chrome.
Jeder halbwegs moderne und auf Kompatibilität ausgerichtete Browser sollte das Skript auch unterstützen.

Der Vorteil des Skripts:
Bisherige (HPM-)Spoiler sollten ohne Probleme und Nachbearbeitung auch autom. ausgeklappt werden.
Nachdem die Seite geladen wurde, werden die betreffenden Spoiler durch ihr Klick-Ereignis aufgeklappt, somit werden Eigenschaften wie z.B. die Klassen genau so gesetzt, wie durch einen manuellen Klick eines Users.

Die Funktion hpm_spoiler(obj) muss dazu nur minimal erweitert werden:
Jeweils zweimal muss setSpoilerCookie(obj); und deleteSpoilerCookie(obj); eingefügt werden.

Zusätzlich müssen dann noch Funktionen für Cookies und MD5 eingebettet werden.
In dem Beispiel im Anhang habe ich die Skripte für MD5 und Cookies wegen der Übersichtlichkeit in extra Dateien gespeichert und mittels script-Tag im src-Attribut verlinkt.
Die Funktionen könnten aber auch problemlos zwischen die Skript-Tags wie das Spoiler-Skript kopiert werden.
Einige zusätzliche Funktionen habe ich dann doch noch direkt in die Datei hinter das leicht veränderte Spoiler-Skript geschrieben.
Die Style-Angaben müssen nicht verändert werden.

Als Letztes muss dann nur noch die Funktion openSpoilersOnload(); nach dem Seitenaufruf ausgeführt werden.
Ob du das wie im Beispiel per onload im Body-Tag durchführst oder das Onload im Skript definierst oder ..., das kannst du so handhaben, wie deine anderen Skripts, hauptsache openSpoilersOnload(); wird aufgerufen.
Ich schlage vor, dass du sie als eine der letzten Funktionen aufrufst, um andere Skripte nicht zu verzögern.


Zum Glück hattest du bereits eine fertige Beispiel-Seite erstellt, so musste ich nicht erst noch die Styles und das Skript aus dem Forum heraussuchen und ein Seiten-Gerüst erstellen.
Ich habe nur noch die Kodierung auf UTF-8 umgestellt und einen Doctype gesetzt (so sieht man auch gleich, ob noch alles valide ist).

Ich denke, das Kopieren der Funktionen ins Forum sollte jetzt nicht mehr das größte Problem sein und belasse es daher erstmal bei den Beispiel-Dateien.

Hinweis:
Nur wenn die Dateien über einen Server aufgerufen werden, können auch Cookies gesetzt werden.
Beim lokalen Aufruf einer Datei setzt der Browser keine Cookies.
Ausnahme bilden Programme wie XAMPP, bei denen man mittels localhost auf Dateien im Dateisystem zugreifen kann (was ja dann eigentlich wieder einem Server entspricht).

Ich bin ja mal gespannt, ob nun alles auch so wie gedacht in einem Forum funktioniert...

#5 RE: Spoiler mit Cookies von Wolfgang 17.05.2011 07:17

avatar

Hallo Florian,
das ist ja der absolute Kracher! Scheint gut zu laufen! Super hinbekommen!

Das MD5-Script habe ich noch nie gesehen. Was macht es denn hier genau?

Nachtrag:
Ich habe eine interessante Eigenart festgestellt!
Spoiler mit dem gleichen Inhalt oder auch leere Spoiler, können nicht unterschiedlich gespeichert werden. Wenn z.B. einer von 4 gleichen Spoilern geöffnet wird, sind nach einem Seitenaufruf alle 4 offen!


Viele Grüße und besten Dank für das komplexe Script
Wolfgang

#6 RE: Spoiler mit Cookies von florian-zier 17.05.2011 16:55

avatar

Hallo Wolfgang,
freut mich, dass das Skript schonmal funktioniert.
Wenn alle Spoiler mit gleichem Inhalt aufgeklappt, dann hast du eigentlich auch schon herausgefunden, was das MD5-Skript macht.

MD5 ist eine Hash-Funktion, sie wird z.B. bei Passwörtern für Logins benutzt.
Der Sinn dahinter ist es, beliebigen Inhalt in einer kurzen Zeichenkette "darzustellen".
Gleiche Inhalte haben den gleichen Hash, somit kann z.B. durch eine Hashfunktion nach einem Download geprüft werden, ob auch alle Bits korrekt übertragen wurden.
Dazu gibt die Bereitstellungswebsite den zugehörigen Hash der Original-Datei, wenn man den Hash dann auf den Download anwendet und den gleichen erhält, heißt das, dass sowohl Download als auch Original übereinstimmen.

PHP hat dafür bereits eine Funktion integriert, für JavaScript habe ich diese Klasse gefunden, die den Algorythmus nachstellt.
Sowohl für die Cookie- als auch für die MD5-Funktionen habe ich oben in den jeweiligen Dateien in einem Kommentar oben eingefügt, von welcher Seite die Quellcodes ursprünglich stammen.
Man muss das Rad ja nicht neu erfinden.

Weil die Spoiler keine Unterscheidungsmerkmale wie IDs haben, können sie eigentlich nur durch den Inhalt unterschieden werden.
Da ich nicht die kompletten Spoiler-Inhalte in einem Cookie speichern wollte, habe ich deren Inhalte gehasht um eine wesentlich kürzere Zeichenlänge zu speichern und trotzdem eindeutig zu bleiben.
Das Skript hasht beim Seitenaufruf alle Inhalte und schaut nach, ob der gleiche Hash bereits im Cookie gespeichert wurde, der Spoiler also geöffnet war.
Sollten mehrere gleiche Inhalte verwendet werden, dann stimmen eben auch die Hashs davon überein, daher wird beim Vergleichen mit dem Cookie jeder dieser Spoiler als geöffnet anerkannt.

Da aber eigentlich nicht mehr als einmal auf das Zeichen identische Inhalte in einem Forum gepostet werden, ist das in der Praxis (so denke ich) eigentlich eher selten der Fall.
Sollte ein Spaßvogel zig gleiche Spoiler zum Vergnügen einfügen, so müssen diese vom User zumindest doch erst geöffnet werden.
Und dann würden schlimmstenfalls mehrere Spoiler gleichzeitig aufgeklappt, dabei reicht es dann ja auch, einen davon zuzuklappen und die Seite neuzuladen (oder Cookies löschen).
Wenn du nichts besonderes davon schreibst, dass mit identischen Inhalten so etwas möglich ist, dann muss man da auch erstmal darauf kommen.
Nur jemand, der sich etwas auskennt, beäugt evtl. die Cookies und hat dann die Erkenntnis, dass es sich um Hashes handeln muss.

Aber wie gesagt, durch fehlende IDs ist dies eigentlich die einzige Möglichkeit, so eine Funktionalität hinzubekommen.

#7 RE: Spoiler mit Cookies von Wolfgang 17.05.2011 23:53

avatar

Wow!
Tolle Idee, tolle Erklärung!

Danke, danke für Deine Mühe.
Gruß
Wolfgang

#8 RE: Spoiler mit Cookies von florian-zier 24.05.2011 16:11

avatar

Hier habe ich nun noch einen Spoiler mit Schließen-Button in Kombination mit der Cookie-Speicherung.

Der Schließen-Button kann natürlich auch ohne Cookie-Speicherung eingebaut werden.
Dazu muss nur die CSS ein wenig erweitert werden:

1
2
3
4
5
6
7
8
9
10
11
12
 
.hpm_spoiler_closebutton {
border-top:1px solid #3c566a;
padding:2px 20px;
font:bold 11px Verdana,Arial,sans-serif;
font-style:italic;
}
.hpm_spoiler_closebutton a {
display:block;
width:100%;
color:black;
text-decoration:none;
}
 



Und dann fehlt noch der HTML-Code, der direkt nach dem Spoiler-Inhalts-DIV eingefügt wird:

1
2
3
 
<div class="hpm_spoiler_closebutton">
<a href="javascript:void(0);" onclick="hpm_spoiler(this.parentNode.parentNode.parentNode.parentNode);">Schließen</a>
</div>
 


Das ganze muss dann natürlich im Foren-Code für einen Spoiler angelegt werden.

Und schon kann der Spoiler über den Button am Ende geschlossen werden.
Änderungen an dessen Design können durch Bearbeitung dessen CSS durchgeführt werden.

Wie es z.B. aussehen kann, ist auf dem Screenshot im Anhang zu sehen.
Hier wurde der Schließen-Text mittels Padding um 20px nach rechts eingeschoben.



Noch ein Hinweis zur Cookie-Speicherung:
Um die Spoiler beim Laden der Seite zu überprüfen, ob sie geöffnet werden sollen, durchsucht das Skript die komplette Dokumentstruktur.
Um die Zeit evtl. ein wenig zu verkürzen, kann das Durchsuchen auf den Inhaltsbereich, welcher auch die Spoiler enthält, beschränkt werden.
Dazu sollte man ein Element der Seite (z.B. Tabelle), welches alle Beiträge umschließt, mit einer ID versehen.

Das Skript wird dann in dieser Zeile:

1
 
var hpm_spoilers = getElementsByClassName('hpm_spoiler', document);
 


... folgendermaßen verändert:

1
 
var hpm_spoilers = getElementsByClassName('hpm_spoiler', document.getElementById('UMGEBENDES_ELEMENT_ID'));
 



Somit wird die Funktion nur die Baumstruktur des umgebenden Elementes durchsuchen.
Kopf- und Fußbereiche werden also nicht mehr überprüft, was bei großen Seiten leicht sehr aufgebläht sein kann.

Xobor Forum Software von Xobor
Einfach ein eigenes Forum erstellen
Datenschutz