Ed Straker: Frage zum Wiki-Artikel „cookies“

problematische Seite

Sehr geehrte Forums-Teilnehmer!

Ich gestalte eine Homepage, auf der der Benutzer zwischen vier Farbdesigns wählen kann. Die entsprechenden Farbangaben befinden sich in ausgelagerten CSS-Dateien (lila.css, gruen.css, rosa.css und schwarz.css), wobei lila.css das Standarddesign ist. Alle anderen Formatierungsangaben befinden sich inline auf den jeweiligen Seiten.

Insgesamt gibt es nur drei Seiten. Die Designauswahl erscheint nur auf der Startseite. Der Wechsel zwischen den Designs funktioniert in allen getesteten Browsern (Firefox, Edge und Chrome auf verschiedenen Android-Geräten) anstandslos.

Das Script switcher.js sieht so aus:

function setActiveStyleSheet(title) {
  var i, a, main;
  for (i = 0; (a = document.getElementsByTagName("link")[i]); i++) {
    if (
      a.getAttribute("rel").indexOf("style") != -1 &&
      a.getAttribute("title")
    ) {
      a.disabled = true;
      if (a.getAttribute("title") == title) a.disabled = false;
    }
  }
}

function getActiveStyleSheet() {
  var i, a;
  for (i = 0; (a = document.getElementsByTagName("link")[i]); i++) {
    if (
      a.getAttribute("rel").indexOf("style") != -1 &&
      a.getAttribute("title") &&
      !a.disabled
    )
      return a.getAttribute("title");
  }
  return null;
}

function getPreferredStyleSheet() {
  var i, a;
  for (i = 0; (a = document.getElementsByTagName("link")[i]); i++) {
    if (
      a.getAttribute("rel").indexOf("style") != -1 &&
      a.getAttribute("rel").indexOf("alt") == -1 &&
      a.getAttribute("title")
    )
      return a.getAttribute("title");
  }
  return null;
}

Nun kommen die Problemzonen. Um das auf der Startseite gewählte Design auch auf die beiden anderen Unterseiten zu übertragen, muss ein Cookie gespeichert werden, auf das die Seiten beim Aufruf zugreifen können. Dieses Script cookie.js sieht so aus:

function setCookie(name, value, days) {
  var expires = "";
  if (days) {
    var date = new Date();
    date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
    expires = "; expires=" + date.toUTCString();
  }
  document.cookie = name + "=" + (value || "") + expires + "; path=/";
}

function getCookie(name) {
  var nameEQ = name + "=";
  var ca = document.cookie.split(";");
  for (var i = 0; i < ca.length; i++) {
    var c = ca[i];
    while (c.charAt(0) == " ") c = c.substring(1, c.length);
    if (c.indexOf(nameEQ) == 0) return;
    c.substring(nameEQ.length, c.length);
  }
  return null;
}

Beim Laden einer der beiden anderen Seiten muss diese das gespeicherte Cookie mit den gewählten Designinformationen abholen und anwenden. Dieses Script onload.js sieht so aus:

window.onload = function (e) {
  var cookie = getCookie("style");
  var title = cookie ? cookie : getPreferredStyleSheet();
  setActiveStyleSheet(title);
};

window.onunload = function (e) {
  var title = getActiveStyleSheet();
  setCookie("style", title, 365);
};

Ich habe die letzten Tage damit verbracht, unzählige Varianten auszuprobieren und mich natürlich auch hier im Forum umgesehen. Ich kann machen was ich will - es funktioniert nicht. Wenn ich von der Startseite mit dem gewählten Farbdesign auf eine der beiden anderen Seiten wechsle, springt das Design wieder auf die Standardwerte zurück. Wo der Hund begraben liegt, habe ich noch nicht herausgefunden und hoffe auf Eure Expertise.

Liegt es am cookie.js und/oder am onload.js oder an den Headern?

Dazu ist zu sagen, dass im Header jeder HTML-Datei die einzelnen CSS- und JS-Dateien verlinkt sind. Das sieht so aus:

<link href="css/lila.css" rel="stylesheet" type="text/css" title="lila">
<link href="css/gruen.css" rel="alternate stylesheet" type="text/css" title="gruen">
<link href="css/rosa.css" rel="alternate stylesheet" type="text/css" title="rosa">
<link href="css/schwarz.css" rel="alternate stylesheet" type="text/css" title="schwarz">
<script src="js/switcher.js" type="text/javascript"></script>
<script src="js/cookie.js" type="text/javascript"></script>
<script src="js/onload.js" type="text/javascript"></script>

Ich habe auch schon versucht, den Link zur switcher.js aus dem Header der beiden Unterseiten zu entfernen, da er nur auf der Startseite benötigt wird. Hat aber auch nicht geholfen. Jetzt bin ich mit meinen rudimentären JavaScript-Kenntnissen am Ende und bitte um Hilfe.

Man möge mir verzeihen, wenn ich als Newbe hier, meinen Hilferuf an falscher Stelle gepostet haben sollte.

Liebe Grüße, Ed

[EDIT]SyntaxHighlighting ergänzt - Felix Riesterer[/EDIT]

  1. problematische Seite

    Lieber Ed,

    schön, dass sich mal jemand die Mühe macht, ein formal einwandfreies Posting zu verfassen. Das liest man sehr gerne. Daher antworte ich Dir auch zu dieser Stunde.

    Dein Link zur „problematischen Seite“ verweist in unser Wiki. Liegt das Problem denn wirklich dort? Ich glaube, eher nicht... Mal sehen.

    Das Script switcher.js sieht so aus:

    Warum hast Du es denn nicht auf einer Beispielseite im Internet zum live-Ansehen bereitgestellt? Wenn Du tatsächlich hier schon mitgelesen hast, dann wird Dir sicher nicht entgangen sein, dass solche live-Beispiele wie z.B. auf jsFiddle eine bessere Möglichkeit bieten Dein Problem nachzuvollziehen.

    function setActiveStyleSheet(title) {
      var i, a, main;
      for (i = 0; (a = document.getElementsByTagName("link")[i]); i++) {
        if (
          a.getAttribute("rel").indexOf("style") != -1 &&
          a.getAttribute("title")
        ) {
          a.disabled = true;
          if (a.getAttribute("title") == title) a.disabled = false;
        }
      }
    }
    

    Wo hast Du diesen Code her? Das schreibst Du nicht. Ist der gecopypasted?

    <link href="css/lila.css" rel="stylesheet" type="text/css" title="lila">
    <link href="css/gruen.css" rel="alternate stylesheet" type="text/css" title="gruen">
    <link href="css/rosa.css" rel="alternate stylesheet" type="text/css" title="rosa">
    <link href="css/schwarz.css" rel="alternate stylesheet" type="text/css" title="schwarz">
    <script src="js/switcher.js" type="text/javascript"></script>
    <script src="js/cookie.js" type="text/javascript"></script>
    <script src="js/onload.js" type="text/javascript"></script>
    

    Warum meinst Du, dass die Browser-eigenen Bedienelemente zum Einstellen des Wunsch-Styles nicht genügen? Hast Du es einmal mit denen probiert? Schaltet der Browser dann auch wieder auf das Default-Stylesheet zurück, wenn man einen Link anklickt?

    Man möge mir verzeihen, wenn ich als Newbe hier, meinen Hilferuf an falscher Stelle gepostet haben sollte.

    Die Stelle war schon richtig. Aber die gebotenen Infos waren wie bei Neulingen üblich etwas ungeschickt dargeboten und nicht vollständig.

    Was ich persönlich zuerst ändern würde, ist die Verwendung eines Cookies. Mir (wie gesagt mir persönlich) liegt es näher, solcherlei Dinge mittels localStorage im Browser zu hinterlegen, weil es erstens kein Verfallsdatum dazu speichert, und weil zweitens die Daten bequemer erreichbar sind. Vergleiche einmal:

    function getPreferredStyleSheet () {
      return localStorage.getItem("preferredStyleSheet");
    }
    
    function setPreferredStyleSheet (title) {
      localStorage.setItem("preferredStyleSheet", title);
    }
    

    Wie Du sehen kannst, ist das Ablegen und Holen einer „mal eben“ im Browser des Seitenbesuchers hinterlegten Information so viel bequemer lösbar, als das Auseinanderfrickeln der Cookiedaten.

    Woran Dein Vorhaben scheitert, kann ich nicht sagen, weil ich kein live-Beispiel habe, an dem ich Deinen Code nachvollziehen kann. Daher nur diese Überlegungen und Rückfragen von mir.

    Liebe Grüße

    Felix Riesterer

    1. problematische Seite

      Hi,

      Dein Link zur „problematischen Seite“ verweist in unser Wiki.

      Das ist doch normal, wenn man den "Frage zur Wiki-Seite"-Link benutzt.

      cu,
      Andreas a/k/a MudGuard

    2. problematische Seite

      Hallo Felix!

      Vielen Dank für die schnelle Antwort und die interessante Anregung mit dem localStorage. Die Lösung gefällt auch mir wesentlich besser als die mit den Cookies. Anfang nächsten Jahres gehe ich in den Ruhestand. Und so wie andere in diesem Alter anfangen, Blumen zu züchten oder im Park Schach zu spielen, beginne ich, mich mit Responsive Webdesign und JavaScript zu beschäftigen. Aber nun zu Deinen Fragen.

      JavaScript

      In vielen Fremdsprachen kennt man nur ein paar Wörter und Redewendungen wie Guten Abend, Gute Nacht, Bitte und Danke. Es fehlen aber Wortschatz und Grammatik, um daraus Sätze zu bilden und sich verständlich zu machen. JavaScript ist eine solche Fremdsprache für mich. Deshalb sind alle von mir verwendeten Scripts, Copy/Paste-Blöcke, die ich per Trial-and-Error einfach ausprobiere und ggf. versuche, sie für meine Bedürfnisse zu adaptieren. Beim Umschalten auf alternative Stylesheets hatte ich irgendwann einfach Glück und es hat geklappt. An die Quellen erinnere ich mich nicht mehr. SELFHTML, Stack Overflow, Code Pen, thestyleworks.de ... – es waren einfach zu viele. Ursprünglich waren die drei Scrips in einer einzigen JS-Datei. Um die Übersicht beim Editieren nicht vollends zu verlieren, habe ich das Script irgendwann in drei Teile gesplittet.

      Live-Ansicht

      Bei dem Projekt handelt es sich um eine Online-Patientenakte einer mir nahestehenden Person. Demnach enthalten die Seiten auch datenschutzrechtlich höchst sensible Informationen. Die Patientenakte (ohne Style Switcher) ist bereits online und liegt in einem .htpasswd geschützten Bereich auf dem Server. Der Switcher wäre in der Tat also nur ein Gimmick und trägt nichts zum eigentlichen Zweck der Seite bei. Ich habe heute dennoch eine gekürzte und anonymisierte Version des Projekts auf https://schweizerkinder.at/patientenakte hochgeladen.

      Einen angenehmen Tag noch und liebe Grüße, Ed

      1. problematische Seite

        Servus!

        Hallo Felix!

        Vielen Dank für die schnelle Antwort und die interessante Anregung mit dem localStorage. Die Lösung gefällt auch mir wesentlich besser als die mit den Cookies. Anfang nächsten Jahres gehe ich in den Ruhestand. Und so wie andere in diesem Alter anfangen, Blumen zu züchten oder im Park Schach zu spielen, beginne ich, mich mit Responsive Webdesign und JavaScript zu beschäftigen.

        Im SELF-Wiki gibt es dieses Tutorial:

        @Rolf B , der auch weiter unten geantwortet hat, hat dieses Beispiel erstellt, in dem nicht die ganzen Stylesheets, sondern nur die Farbwerte als custom properties geändert werden:

        Herzliche Grüße

        Matthias Scharwies

        --
        Ich habe heute rausgefunden, dass in das Pizzafach meines Rucksacks auch ein Laptop passt!
    3. problematische Seite

      Ich scheine mittlerweile selbst einen kleinen Etappensieg errungen zu haben. Die <a href Anweisungen der Buttons auf die man klickt, um den Farbwechsel herbeizuführen sahen – am Beispiel der grünen Farbe – in HTML bis jetzt so aus:

      <a href="#" onclick="setActiveStyleSheet('gruen'); return false;"></a>
      

      Nun habe ich das so abgeändert, bzw. ergänzt:

      <a href="#" onclick="setActiveStyleSheet('gruen'); setCookie('gruen'); return false;"></a>
      

      Hurra! Nun wird, wie ich in den Seiteninformationen des Browsers sehen kann, tatsächlich ein Cookie mit dem Farbnamen gespeichert.

      Cookie für grünes CSS

      Cookie für rosa CSS

      Somit dürfte mein cookie.js keinen Fehler haben. Bloß die Anweisung es auszuführen fehlte in den Links. Sehe ich das soweit richtig?

      Stellt sich also noch die Frage, wie ich es bewerkstellige, dass sich die nächste aufgerufene Seite genau dieses Cookie holt und anwendet. Da die Lösung für das Setzen des Cookies nun relativ simpel war (wenn man drauf kommt), hoffe ich auch das letzt Problem noch mit Eurer Hilfe lösen zu können.

      Zur Erinnerung, hier noch einmal der Link zur anonymisierten Live-Version meines Patientenakten-Projekts: https://schweizerkinder.at/patientenakte

      LG, Ed

      1. problematische Seite

        @@Ed Straker

        <a href="#" onclick="setActiveStyleSheet('gruen'); setCookie('gruen'); return false;"></a>
        

        Hurra!

        Das „Hurra!“ ist etwas verfrüht.

        <a href="#"> ist ein sicheres Zeichen für einen Fehler; <a href="#" onclick=""> ist ein todsicheres.

        Links führen zu anderen Stellen im Web oder zu anderen Stellen auf der aktuellen Seite. Für Aktionen auf einer Seite musst du Buttons (<button>)verwenden:

        <button onclick="setActiveStyleSheet('gruen'); setCookie('gruen');">
        

        Siehe Buttons vs. Links.

        (Du solltest Eventhandler im JavaScript notieren (addEventListener()), nicht im HTML per onclick.)

        Und der Button braucht eine Beschriftung! Diese kann visuell versteckt werden, aber sie muss vorhanden sein:

        <button onclick="setActiveStyleSheet('gruen'); setCookie('gruen');">
          <span class="visually-hidden">grün</span>
        </button>
        

        (mit den Styles aus der verlinkten Quelle)

        🖖 Живіть довго і процвітайте

        --
        Ad astra per aspera
      2. problematische Seite

        Moin Ed,

        in Ergänzung zu Gunnars Antwort:

        Die <a href Anweisungen der Buttons auf die man klickt […]

        Das a-Element zeichnet einen Link aus, für Buttons gibt es button!

        Viele Grüße
        Robert

        1. problematische Seite

          Hi,

          in Ergänzung zu Gunnars Antwort:

          Die <a href Anweisungen der Buttons auf die man klickt […]

          Das a-Element zeichnet einen Link aus, für Buttons gibt es button!

          Ich zitiere hier mal Gunters Posting:

          <a href="#"> ist ein sicheres Zeichen für einen Fehler; <a href="#" onclick="…"> ist ein todsicheres.

          Links führen zu anderen Stellen im Web oder zu anderen Stellen auf der aktuellen Seite. Für Aktionen auf einer Seite musst du Buttons (<button>)verwenden:

          Was genau hast Du jetzt ergänzt?

          cu,
          Andreas a/k/a MudGuard

          1. problematische Seite

            @@MudGuard

            Ich zitiere hier mal Gunters Posting:

            Werden jetzt alle Namen eingedeutscht, SchmutzWächter?[1]

            Nee, ich bin Südschwede!

            Was genau hast Du jetzt ergänzt?

            Die Frage hatte ich mir auch gestellt.

            🖖 Живіть довго і процвітайте

            --
            Ad astra per aspera

            1. Ich hab kurz überlegt, ob ich’s mit ae schreiben sollte. ↩︎

            1. problematische Seite

              Hi,

              Ich zitiere hier mal Gunters Posting:

              Werden jetzt alle Namen eingedeutscht, SchmutzWächter?[^1]

              ich red mich jetzt mal auf Autokorrektur raus.

              Ich hab kurz überlegt, ob ich’s mit ae schreiben sollte.

              Kann man das anders schreiben als mit ae?

              cu,
              Andreas a/k/a MudGuard

      3. problematische Seite

        Lieber Ed,

        Zur Erinnerung, hier noch einmal der Link zur anonymisierten Live-Version meines Patientenakten-Projekts: https://schweizerkinder.at/patientenakte

        wenn ich einen der unteren Links anklicke, erhalte ich in der Konsole meines Firefox diese Fehlermeldung:

        Uncaught ReferenceError: getPreferredStyleSheet is not defined onload https://schweizerkinder.at/patientenakte/js/onload.js:3 EventHandlerNonNull* https://schweizerkinder.at/patientenakte/js/onload.js:1

        Das ist sicherlich die Ursache, warum die vom Benutzer getroffene Farbwahl nicht angewendet wird. Das hat damit zu tun, dass Du Deinen Code auf diverse JavaScript-Dateien verteilst, die dann alle geladen werden müssen, damit die benötigten Funktionen alle verfügbar sind. So rufst Du in Datei A eine Funktion auf, die aber in Datei B notiert ist, welche vielleicht aus welchen Gründen auch immer nicht geladen werden konnte.

        Wenn Du allen Code in einer JavaScript-Datei hast, dann brauchst Du auch nur diese eine zu pflegen. Und dann hast Du auch die Chance zu verstehen, was Du da tust! Lass' mich 'mal den Anfang machen:

        document.addEventListener("DOMContentLoaded", function () {
          function createColourChooser () {
          }
        
          function getPreferredStyle () {
          }
        
          function setPreferredStyle (URL) {
          }
        
          setPreferredStyle(
            getPreferredStyle()
          );
          createColourChooser();
        });
        

        Aber lass' mich noch viel tiefer in die Kritik einsteigen:

        1. Diejenigen Elemente einer Seite, die ohne JavaScript keine Funktionalität haben, sollten mit JavaScript dort hinein geschrieben werden. Sie grundsätzlich im HTML-Dokument zu haben, verstößt gegen diesen Grundsatz.
        2. Warum lese ich JavaScript-Code im HTML-Dokument? Dieser gehört da nicht hin, weil Du JavaScript-Code nur in extern geladenen JavaScript-Dateien hast. Daten, die JavaScript aus dem HTML-Dokument als sozusagen Arbeitsdaten entnehmen soll, notierst Du dort völlig anders, und zwar mit HTML-Mitteln wie die data-Attribute.
        3. Was ist eigentlich ein <div class="wrapper">? In HTML gibt es inzwischen (HTML5) einige Blocklevel-Elemente, die man stattdessen verwenden kann, wie z.B. main, section, article, aside usw. Nimm doch eines von diesen, dann sparst Du Dir auch den Klassennamen gleich mit, denn Dein Selektor im CSS-Code wird dann diesen Elementnamen verwenden.
        4. Tabellen sind dazu da, tabellarische Inhalte anzuzeigen, aber nicht, um die Seite insgesamt zu layouten. Du verwendest eine dreispaltige Tabelle, bei der die erste Spalte (links) dafür sorgt, dass ein Abstand vom linken Rand beibehalten wird. Dafür verwendet man passende CSS-Eigenschaften, wie z.B. margin. Entferne also bitte diese jeweils erste Tabellenzelle in Deinen Tabellenzeilen.
        5. Du willst eine Tabelle, bei der links eine Eigenschaft steht und rechts der zugehörtige Wert (wie bei Schlüssel-Wert-Paaren). Das bedeutet, dass Deine linke Spalte einen Tabellen-Header benötigt, also ein <th>-Element. Wenn Dir dessen Darstellung nicht gefällt, dann passe sie mit CSS entsprechend an. Aber nur aus Gründen der Darstellung „nur“ ein td-Element zu verwenden ist semantisch falsch.
        6. Deine Klassennamen wie „empty“, „erstespalte“ und „informationen“ kannst Du entsorgen, weil Du auf die erste Tabellenspalte verzichtest (siehe oben Punkt 4), um nur noch zwei Spalten übrig zu haben, bei denen die erste mit einem th-Element (siehe oben Punkt 5) und die zweite mit einem td-Element realisiert ist. Damit kannst Du mittels CSS und dem passenden Selektor ganz klar zwischen diesen Spalten unterscheiden, ohne Klassennamen zu benötigen. Das ist einer der großen Vorteile von semantischem HTML! Außerdem habe ich in Deinem CSS gesehen, dass Du auch Pseudoklassen wie :nth-of-type() verwendest, womit man das auch machen könnte, was meiner Meinung nach aber unnötig umständlicher wäre!
        7. Die visuelle Unterteilung Deiner Tabelle durch Zwischenüberschriften machst Du in der Tat mit th-Elementen, die ein colspan-Attribut haben, damit die th-Zelle über beide Spalten geht. Das ist gut so! Um aber ihre Darstellung von den regulären th-Elementen in den ersten Spalten zu unterscheiden, kannst Du im CSS einen Attribut-Selektor verwenden, und zwar am Besten den, der die Präsenz des Attributs prüft (der genaue Wert des colspan-Attributs ist ja hier egal).
        8. Es ist visuell nur eine Tabelle zu erkennen, im Quelltext stehen aber mehrere nacheinander notiert. Wozu? Das kann ruhig eine Tabelle sein. Mit den oben angemerkten Verbesserungen ist das Ergebnis schlanker, effizienter und besser zu pflegen.
        9. Deine Button-Navigation unten möchte eine Navigation (nav) sein. Dazu kommt noch, dass die Links einen anklickbaren Verweistext benötigen, damit auch blinde Menschen diese Navi verwenden können. Für sehende Menschen kann man die Beschriftung visuell verstecken.
        10. Du hast da im Quelltext eine lustige Erinnerungsnotiz zur (scheinbaren!) Notwendigkeit von inline-Styles bezüglich eines Mailto-Links. Komisch, dass Du hier keinen Klassennamen verwendest, wo Du doch bei allen Tabellenzellen einen hattest! Wenn nun Deine Button-Navi in einem nav-Element sitzt, kannst Du Deinen Links dort eine feste Breite geben, die auch für den Mailto-Link gilt - passenden Selektor vorausgesetzt. Ein Hoch auf semantisches HTML!

        Schau mal in dieses jsFiddle, denn da habe ich angefangen, meine Kritik umzusetzen.

        Liebe Grüße

        Felix Riesterer

        1. problematische Seite

          @@Felix Riesterer

          1. Diejenigen Elemente einer Seite, die ohne JavaScript keine Funktionalität haben, sollten mit JavaScript dort hinein geschrieben werden. Sie grundsätzlich im HTML-Dokument zu haben, verstößt gegen diesen Grundsatz.

          Dagegen würde ich verstoßen. Es ist performanter (und einfacher), die Elemente gleich im DOM zu haben als sie nachträglich mit JavaScript erst hineinzubauen.

          Allerdings sollten Elemente, die keine Funktionalität haben, im UI nicht sichtbar sein, also das hidden-Attribut gesetzt haben. Mit dem JavaScript, welches ihnen Funktionalität verleiht, wird dann .hidden = false gesetzt.

          Salvatorische Klausel: Die Gültigkeit deiner anderen Anmerkungen ist hiervon nicht beeinträchtigt.

          🖖 Живіть довго і процвітайте

          --
          Ad astra per aspera
          1. problematische Seite

            Lieber Gunnar,

            Es ist performanter (und einfacher), die Elemente gleich im DOM zu haben als sie nachträglich mit JavaScript erst hineinzubauen.

            das ist richtig, und gilt für Fälle, in denen das HTML-Dokument schon weiß, dass ein JavaScript das benötigen wird. Es kommt also wieder einmal darauf an.

            In Fällen, in denen man sich eine Funktionalität ins Dokument zieht, indem man eine (externe/fremde) JavaScript-Komponente „nachlädt“, sollte das HTML-Dokument ahnungslos hinsichtlich der Bedürfnisse für diese Komponente sein. Insbesondere dann, wenn die JavaScript-Komponente irgendwann aktualisiert wurde und in ihrer neuen Version andere Voraussetzungen benötigt. In solchen Fällen ist es sinvoll (und vielleicht weniger performant), wenn die Komponente selbst dafür sorgt, dass alles Benötigte auch genau so im Dokument vorhanden ist.

            Liebe Grüße

            Felix Riesterer

  2. problematische Seite

    Hi,

    Insgesamt gibt es nur drei Seiten. Die Designauswahl erscheint nur auf der Startseite.

    d.h. sie wird vom Besucher ggf. gar nicht gesehen, weil der über die Suchmaschine direkt auf eine der nicht-Startseiten geleitet wird.

    Ansonsten: mach's wie Felix vorgeschlagen hat, also mit dem localStorage.

    cu,
    Andreas a/k/a MudGuard

  3. problematische Seite

    @@Ed Straker

    Ich gestalte eine Homepage, auf der der Benutzer zwischen vier Farbdesigns wählen kann. Die entsprechenden Farbangaben befinden sich in ausgelagerten CSS-Dateien (lila.css, gruen.css, rosa.css und schwarz.css), wobei lila.css das Standarddesign ist.

    Ich würde da nicht jeweils ein Stylesheet für ein Farbschema machen und diese umschalten, sondern für einen Farbwechsel einfach nur eine Klasse am Root-Element umschalten:

    <html class="green">
    

    Die Farben werden in custom properties festgehalten:

    :root, :root.purple {
      --background-color: plum;
      --text-color: black;
      --accent-color: rebeccapurple;
      background-color: var(--background-color);
      color: var(--text-color);
    }
    
    :root.green {
      --background-color: palegreen;
      --text-color: black;
      --accent-color: seagreen;
    }
    
    :root.black {
      --background-color: #222;
      --text-color: white;
      --accent-color: wheat;
    }
    
    h1 { color: var(--accent-color) }
    

    Alle anderen Formatierungsangaben befinden sich inline auf den jeweiligen Seiten.

    Das ist wohl keine so gute Idee.

    Um das auf der Startseite gewählte Design auch auf die beiden anderen Unterseiten zu übertragen, muss ein Cookie gespeichert werden, auf das die Seiten beim Aufruf zugreifen können.

    Muss nicht. Dass localStorage Mittel der Wahl ist, sagte Felix ja schon.

    🖖 Живіть довго і процвітайте

    --
    Ad astra per aspera
    1. problematische Seite

      Hallo Gunnar,

      ich schreib's mal hier: localStorage ist nur bedingt das Mittel der Wahl. Verwendet man ihn, braucht man eine Speichererlaubnis vom User. Oder eine Dissertation darüber, ob man eine solche Einstellung als legitimes Interesse definieren kann. Zumindest muss man über die Speicherung informieren.

      Wenn man die sowieso hat - okay. Hat man die nicht, sollte man besser den sessionStorage verwenden. Der funktioniert genauso, wird aber beim Schließen des Fensters verworfen und braucht damit analog zu Sessioncookies keine Speichererlaubnis.

      Rolf

      --
      sumpsi - posui - obstruxi
      1. problematische Seite

        Danke für die zahlreichen Empfehlungen und die Mühe, die sich alle Beteiligten bist jetzt gemacht haben. Ich versuche in einem Rutsch einige Argumente zu erörtern.

        • Suchmaschinen sind kein Thema, da die Seite in einem .htpasswd geschützten Bereich auf dem Server liegt.

        • localStorage scheint wohl doch nicht gas Gelbe vom Ei zu sein, wenn ich mir dir diversen DSGVO-Bestimmungen so ansehe.

        • Der Farbwechsel funktionierte ja von Anfang an. Meine Lösung mag zwar etwas umständlich wirken und eleganter zu bewerkstelligen sein, aber es tut was es tun soll. Insofern möchte ich (zumindest fürs Erste) da nicht noch ein Fass aufmachen.

        • Das Problem scheint am Setzen des Cookies zu liegen. Und wenn das nicht gespeichert ist, kann es auch nicht von der nächsten aufgerufenen Seite angewendet werden.

        • Die Problemkinder sind das cookie.js und evtl. auch das onload.js. Letzteres kann ich aber erst endgültig beurteilen, wenn das cookie.js erstmal das tut was es tun soll. Irgendwo habe ich da einen Error eingebaut.

        Liebe Grüße derweil an alle,

        Ed

        1. problematische Seite

          Hallo

          • localStorage scheint wohl doch nicht gas Gelbe vom Ei zu sein, wenn ich mir dir diversen DSGVO-Bestimmungen so ansehe.

          In Hinsicht auf die DSGVO unterscheiden sich Cookies und LocalStorage nicht. Du willst Daten auf dem Rechner speichern, die der Wiedererkennbarkeit des Benutzers dienen. Also brauchst du, abseits von für den Betrieb eines Dienstes notwendigen Daten, die Zustimmung des Benutzers. Das gilt in beiden Fällen.

          • Das Problem scheint am Setzen des Cookies zu liegen. Und wenn das nicht gespeichert ist, kann es auch nicht von der nächsten aufgerufenen Seite angewendet werden.

          Analog bei Daten im LocalStorage: es muss etwas gespeichert werden, damit es beim nächsten Seitenaufruf gelesen und ausgewertet werden kann.

          Der (schon erwähnte) Vorteil von LocalStorage gegenüber Cookies ist, dass die Daten nicht bei jedem Seitenaufruf wieder und wieder mit zum Server geschickt werden. Der Nachteil, der sich daraus ergibt, ist, dass die Daten auf dem Server nicht zur Verfügung stehen und damit nicht von einem Skript auf dem Server für irgendwas benutzt werden können.

          Wenn du eine serverseitige Lösung erstellen würdest und die Auswahl eine Browsersitzung überleben sollen würde, bräuchtest du Cookies. Für eine rein clientseitige Lösung ist LocalStorage zu bevorzugen. Sind die Daten im LocalStorage und nicht im ebenfalls verfügbaren SessionStorage gespeichert, überlebt die gespeicherte Information auch eine Browsersitzung.

          Tschö, Auge

          --
          „Habe ich mir das nur eingebildet, oder kann der kleine Hund wirklich sprechen?“ fragte Schnapper. „Er behauptet, nicht dazu imstande zu sein“ erwiderte Victor. Schnapper zögerte (…) „Nun …“ sagte er schließlich, „ich schätze, er muss es am besten wissen.“ Terry Prattchett, Voll im Bilde
          1. problematische Seite

            Hi,

            • localStorage scheint wohl doch nicht gas Gelbe vom Ei zu sein, wenn ich mir dir diversen DSGVO-Bestimmungen so ansehe.

            In Hinsicht auf die DSGVO unterscheiden sich Cookies und LocalStorage nicht.

            Das sehe ich anders. Coookies werden beim Request an den Server geschickt, der Inhalt des localStorage nicht.

            cu,
            Andreas a/k/a MudGuard

            1. problematische Seite

              Hallo

              • localStorage scheint wohl doch nicht gas Gelbe vom Ei zu sein, wenn ich mir dir diversen DSGVO-Bestimmungen so ansehe.

              In Hinsicht auf die DSGVO unterscheiden sich Cookies und LocalStorage nicht.

              Das sehe ich anders. Coookies werden beim Request an den Server geschickt, der Inhalt des localStorage nicht.

              Das ist korrekt. Aber ist das in Hinsicht darauf, ob nach den Bestimmungen der DSGVO ein Einverständnis zur Speicherung von personenbeziehbaren Daten[1] erforderlich ist, relevant? Meiner Meinung nach ist es das nicht.

              Mit beiden Techniken würden Daten gespeichert, die den Browserbenutzer beim nächsten Aufruf einer Seite des selben Angebots wiedererkennbar machen sollen, damit der zuvor vom Benutzer ausgesuchte Seitenstil angewendet werden kann. Der Zweck ist also der Gleiche. Dass und worin sich die Techniken unterscheiden, hatte ich in meinem Vorposting an anderer Stelle ja auch schon versucht zu beschreiben.

              Tschö, Auge

              --
              „Habe ich mir das nur eingebildet, oder kann der kleine Hund wirklich sprechen?“ fragte Schnapper. „Er behauptet, nicht dazu imstande zu sein“ erwiderte Victor. Schnapper zögerte (…) „Nun …“ sagte er schließlich, „ich schätze, er muss es am besten wissen.“ Terry Prattchett, Voll im Bilde

              1. Persönliche Daten sollten hier nicht im Spiel sein. ↩︎

              1. problematische Seite

                Hallo Auge,

                hm, das ist durchaus bedenkenswert. Ist eine Farbauswahl kein personenbezogenes Datum? DSGVO Artikel 4:

                „personenbezogene Daten“ (sind) alle Informationen, die sich auf eine identifizierte oder identifizierbare natürliche Person (im Folgenden „betroffene Person“) beziehen; als identifizierbar wird eine natürliche Person angesehen, die direkt oder indirekt, insbesondere mittels Zuordnung zu einer Kennung wie einem Namen, zu einer Kennnummer, zu Standortdaten, zu einer Online-Kennung oder zu einem oder mehreren besonderen Merkmalen, die Ausdruck der physischen, physiologischen, genetischen, psychischen, wirtschaftlichen, kulturellen oder sozialen Identität dieser natürlichen Person sind, identifiziert werden kann;

                Wenn der Besucher nicht weiter identifiziert wird und NUR die Farbauswahl gespeichert wird, könnte man sagen: es handelt sich nicht um personenbezogene Daten. Wenn der Benutzer nachträglich identifiziert wird, dann wieder schon, d.h. man muss den Gesamtablauf im Blick haben, um zu entscheiden, ob die Speicherung oder Verarbeitung erlaubt ist oder ob man nachfragen und eine Datenschutzerklärung vorlegen muss.

                Wird zum Beispiel die Farbauswahl verwendet, um zur Farbe passende Werbung zu generieren, findet eine automatische Verarbeitung von Daten statt, die der Benutzer eingegeben hat. Hat man nur 3 User, kann ein Farbprofil identifizierend sein. Bei 3000 Usern eher nicht. Da im Grenzfall ein Richter entscheidet, sollte man immer darauf achten, in Richtung der vorsichtigen Seite zu irren. Weswegen uns die Welt mit Keksbannern zuschmeißt.

                Aber wie gesagt: sessionStorage statt localStorage führt zu einer temporären Speicherung, so wie ein Session Cookie, und da kann ich problemlos Daten speichern. Die sind im Hoheitsbereich des Users und nicht persistent. Ich muss nur aufpassen, ob und wie sie verarbeitet werden - da kommen dann weitere DSGVO-Anforderungen ins Spiel.

                Rolf

                --
                sumpsi - posui - obstruxi
                1. problematische Seite

                  Hi,

                  hm, das ist durchaus bedenkenswert. Ist eine Farbauswahl kein personenbezogenes Datum? DSGVO Artikel 4:

                  Selbst wenn, der Seitenbetreiber speichert diese, wenn sie nur im LocalStorage liegt, nicht bei sich.

                  Wenn der Besucher nicht weiter identifiziert wird und NUR die Farbauswahl gespeichert wird, könnte man sagen: es handelt sich nicht um personenbezogene Daten. Wenn der Benutzer nachträglich identifiziert wird, dann wieder schon,

                  Wirklich? Solange die Farbinformation nur im LocalStorage liegt, kann der Seitenbetreiber nichts damit anfangen, selbst wenn er den Benutzer identifiziert. Denn was er nicht hat, kann er nicht benutzen.

                  Wird zum Beispiel die Farbauswahl verwendet, um zur Farbe passende Werbung zu generieren, findet eine automatische Verarbeitung von Daten statt,

                  Solange die Farbinformation nur im LocalStorage liegt ...

                  Aber wie gesagt: sessionStorage statt localStorage führt zu einer temporären Speicherung, so wie ein Session Cookie, und da kann ich problemlos Daten speichern. Die sind im Hoheitsbereich des Users und nicht persistent.

                  Auch im LocalStorage sind die Daten im Hoheitsbereich des Users.

                  cu,
                  Andreas a/k/a MudGuard

                  1. problematische Seite

                    Hallo MudGuard,

                    Solange die Farbinformation nur im LocalStorage liegt, kann der Seitenbetreiber nichts damit anfangen,

                    Er kann sie durch JavaScript abrufen und auf dem Gerät des Anwenders verarbeiten (führt der Anwender dann eine Auftragsdatenverarbeitung für den Seitenbetreiber durch?!?!).

                    Er kann sie auch als Argument für einen Webservice verwenden.

                    Rolf

                    --
                    sumpsi - posui - obstruxi
                    1. problematische Seite

                      Hallo

                      Solange die Farbinformation nur im LocalStorage liegt, kann der Seitenbetreiber nichts damit anfangen,

                      Er kann sie durch JavaScript abrufen und auf dem Gerät des Anwenders verarbeiten …

                      Er kann sie auch als Argument für einen Webservice verwenden.

                      Ich denke mal, da liegt der Hasse im Pfeffer. Ja, die Daten befinden sich auf dem Gerät des Benutzers. Aber auch: ja, der Seitebetreiber hat darauf Zugriff. Er kann sie auf dem Gerät des Benutzer verarbeiten (hier: gewünschtes Stylesheet laden [1]), er kann sie aber auch per Ajax/Fetch an seinen Server übertragen und die Daten dort weiterverarbeiten.

                      Davon abgesehen steht immer noch der Punkt, dass mit dem auf dem Gerät des Benutzers gespeicherten Datum dieser wiedererkennbar ist, auch ohne den Namen der natürlichen Person, die vor dem Display sitzt. Daher benutze ich hier ja auch den Begriff „personenbeziehbare Daten“ im Gegensatz zu „persönliche Daten“ [2].

                      Tschö, Auge

                      --
                      „Habe ich mir das nur eingebildet, oder kann der kleine Hund wirklich sprechen?“ fragte Schnapper. „Er behauptet, nicht dazu imstande zu sein“ erwiderte Victor. Schnapper zögerte (…) „Nun …“ sagte er schließlich, „ich schätze, er muss es am besten wissen.“ Terry Prattchett, Voll im Bilde

                      1. Dass das wiederum durch einen Request beim Server erfolgt und damit Datenspuren erzeugen kann, lassen wir mal beiseite. ↩︎

                      2. Wobei hier, wenn man es ganz genau nehmen wollte, eigentlich „gerätebeziehbare Daten“ oder gar „browserbeziehbare Daten“ korrekt wäre. ↩︎

                    2. problematische Seite

                      Hi,

                      Solange die Farbinformation nur im LocalStorage liegt, kann der Seitenbetreiber nichts damit anfangen,

                      Er kann sie durch JavaScript abrufen und auf dem Gerät des Anwenders verarbeiten (führt der Anwender dann eine Auftragsdatenverarbeitung für den Seitenbetreiber durch?!?!).

                      Ich zitiere mich mal selbst:

                      Solange die Farbinformation nur im LocalStorage liegt

                      Er kann sie auch als Argument für einen Webservice verwenden.

                      DAS hat aber NIX mit dem localStorage zu tun.

                      cu,
                      Andreas a/k/a MudGuard

                      1. problematische Seite

                        Hallo MudGuard,

                        aber mit der Annahme, der Betreiber könne nichts damit anfangen. Ich meine ja nur: man muss das Gesamtkunstwerk betrachten, um zu entscheiden, was zulässig ist oder nicht.

                        Rolf

                        --
                        sumpsi - posui - obstruxi
                        1. problematische Seite

                          <button> statt <a href="#">, Cookies, localStorage, DSGVO… Ich glaube, wir verzetteln uns hier mittlerweile ein wenig und verlieren die eigentliche Frage aus den Augen.

                          Zu Erinnerung: Ich ändere per per Klick auf ein kleines Auswahlmenü in einer index.html und einem switcher.js einige Design-Farben. Diese bleiben beim Wechsel auf eine andere HTML-Seite nicht erhalten.

                          Die Scripts cookie.js und/oder loader.js müssen fehlerbehaftet sein. Ein oder mehrere Denkfehler, gepaart mir mangelnden JavaScript Kenntnissen meinerseits.

                          Vielleicht schaffen wir es irgendwie wieder back to the roots? Ich bin auf Eure Hilfe angewiesen, da ich ansonsten noch ewig herumexperimentieren und im Nebel der Unwissenheit stochern muss.

                          Danke, Ed

                          1. problematische Seite

                            @@Ed Straker

                            <button> statt <a href="#">, Cookies, localStorage, DSGVO… Ich glaube, wir verzetteln uns hier mittlerweile ein wenig und verlieren die eigentliche Frage aus den Augen.

                            Zu Erinnerung: Ich ändere per per Klick auf ein kleines Auswahlmenü in einer index.html und einem switcher.js einige Design-Farben.

                            Schön für dich. Damit nicht nur du, sondern alle das problemlos tun können, gehört „<button> statt <a href="#">“ mit zur eigentlichen Frage.

                            Und dass localStorage für etwas, das den Server nichts angeht, die bessere Technologie als Cookies ist, gehört auch zur eigentlichen Frage.

                            „Willkommen hier im Forum. Du kannst hier Antworten auf deine gestellten Fragen erwarten, rechne aber auch mit Antworten auf deine nicht gestellten Fragen 😉“
                            @Tabellenkalk (aus den gesammelten Werken)

                            Die Scripts cookie.js und/oder loader.js müssen fehlerbehaftet sein.

                            Warum sollte man sich die Mühe machen, sich das genauer anzusehen, wenn die Antwort ‚Verwende keine Cookies‘ ist?

                            🖖 Живіть довго і процвітайте

                            --
                            Ad astra per aspera
                            1. problematische Seite

                              Warum sollte man sich die Mühe machen, sich das genauer anzusehen, wenn die Antwort ‚Verwende keine Cookies‘ ist?

                              Vielleicht, weil ich höflich darum gebeten hatte?

                              Die <a href="#"> habe ich übrigens schon vor zwei Tagen durch <button> Tags ersetzt, was für die ursprüngliche Frage aber ziemlich irrelevant ist.

                              Irgendwie scheinen Anfragen in Foren oft nach einem ganz ähnlichen Schema abzulaufen. Jemand stellt die Frage, wie man z.B. den Akku bei einem Laptop des Herstellers XYZ ausbauen kann. Ein paar Antworten später heißt es dann schon, warum man den Akku ausbauen möchte und weshalb man sich nicht einen Laptop der Firma ABC gekauft hat, weil es bei diesem ganz einfach ginge. In der Folge diskutieren dann die Teilnehmer nur noch, ob die Produkte der Hersteller ABC, XYZ oder 123 besser sind. Das ist frustrierend. 😪

                              Ich beende das hier und jetzt für mich. Auf den einzigen Fortschritt bei der Lösung meines Problems bin ich selbst gekommen. Entweder schaffe ich den Rest nach dem Motto „Hilf dir selbst, dann hilft dir Gott“ auch noch irgendwann oder ich lasse es bleiben und züchte in der Pension doch Blumen oder irgendwelche psychoaktive Substanzen. 😄

                              Danke an alle Teilnehmenden Diskutanten und den einen oder anderen Tipp,

                              Ed

                              1. problematische Seite

                                @@Ed Straker

                                Warum sollte man sich die Mühe machen, sich das genauer anzusehen, wenn die Antwort ‚Verwende keine Cookies‘ ist?

                                Vielleicht, weil ich höflich darum gebeten hatte?

                                Warum willst du weiter deinem Holzweg folgen? Dir wurde gesagt ‚Verwende localStorage.‘ Hast du dir die Mühe gemacht?

                                Die <a href="#"> habe ich übrigens schon vor zwei Tagen durch <button> Tags ersetzt

                                Fein.

                                Ich beende das hier und jetzt für mich.

                                Tja, wärst du mal den Hinweisen gefolgt. Mit button und .visually-hidden und localStorage kommt man recht schnell zu einer Lösung.

                                🖖 Живіть довго і процвітайте

                                --
                                Ad astra per aspera
                                1. problematische Seite

                                  Lieber Gunnar,

                                  kommt man recht schnell zu einer Lösung.

                                  1. Er ist schon weg.
                                  2. Ich hatte schon eine Lösung gepostet.

                                  Liebe Grüße

                                  Felix Riesterer