Partage
  • Partager sur Facebook
  • Partager sur Twitter

Changer Thème sombre-clair au clic

Sujet résolu
    22 septembre 2022 à 16:44:39

    Bonjour,

    Je souhaite mettre un bouton pour changer de thème : sombre/clair. Dans tous les tutos qu'on trouve sur internet, le thème n'est pas sauvegardé quand on change de page.

    J'ai donc essayé d'en faire un moi-même. Pour conserver le thème en mémoire, je sauvegarde le thème en session php.

    Pour cela, j'ai utilisé du JS pour le bouton, du PHP pour la sauvegarde en session. Pour correspondre le JS avec le PHP, j'ai utilisé Ajax.

    Voici mon code :

    JS (je mets une image, car l'Ajax est bloqué ici) :

    Le php de la page data-change-theme.php :

    if (session_status() !== PHP_SESSION_ACTIVE) {
        session_start();
    }
    
    $change = null;
    
    if (isset($_GET["change"])) {
        $change = intval($_GET["change"]); // Recup info dans data-theme-sombre.php?change=
    }
    
    
    $request = [
        'isDark' => 0
    ];
    // $request['isDark'] = 0; // Equivalent
    
    if ($change == 1) {
        if ($_SESSION['darktheme'] === 1) {
            $_SESSION['darktheme'] = 0;
            $request['isDark'] = 0; // Pareil que $request = ['isDark' => 0]
        }
        else {
            $_SESSION['darktheme'] = 1;
            $request['isDark'] = 1; // Pareil que $request = ['isDark' => 1]
        }
    }
    elseif ($change == 0) {
        if ($_SESSION['darktheme'] === 1) {
            $request['isDark'] = 1;
        }
        else {
            $_SESSION['darktheme'] = 0;
            $request['isDark'] = 0;
        }
    }
    
    
    
    // print_r($request);
    /* Affiche :
    Array(
        [isDark] => 1
    )
    */
    
    /*
    $request = ['isDark' => 0]; // Tableau PHP
    echo json_encode($request); // On obtient une Chaine JSON {"isDark:1"} ou {"isDark:0"}
    */
    
    echo json_encode($request); // On obtient une Chaine JSON {"isDark:1"} ou {"isDark:0"}. C'est pour que le JS/Ajax puisse avoir accès à cette donnée. Car le JS ou Ajax ne sait pas lire de variable PHP.

    Tout semble marcher parfaitement, mais j'ai un message d'erreur dans console.log :

    Uncaught SyntaxError: Unexpected token < in JSON at position 0

        at JSON.parse (<anonymous>)

        at XMLHttpRequest.xhttp.onload

    Si je recharge la page, l'erreur n'apparait plus. Comment corriger ce message d'erreur ? Merci d'avance.

    • Partager sur Facebook
    • Partager sur Twitter
      22 septembre 2022 à 18:08:15

      Bonjour si tu utilises le js pour le thème autant utiliser js jusqu'au bout, surtout que la session php si tu ne l'étend pas sera détruite à la fermeture du navigateur / a la mise hors tension du pc...

      utiliser le localStorage peut être une bonne solution, quand je crée quelque chode nécessitant un changement de thème je me sert de variables css pour faire un exemple de ce dont je parle je me bases sur 5 fichiers

      1- theme.css qui sera intégré sur toute page nécessitant la mise en place du thème ( vu qu'o' va fonctionner avec js si js edt désactivé ce fichier offrira le thème par défaut). Donc tu l'auras compris à minima il contiendra les variables css nécessaire au thème

      2-theme.js qui servira de script js pour le changement de thème ( en general je lui fais envoyer un event au changement de thème pour que les cas particuliers puissent être géré)

      3- dans un dossier theme ou peu importe un fichier theme.json qui contiendra la liste des nom de  themes ( ici dark et light pour toi)

      4 et 5 deux fichiers dark.json et light.json ( par rapport au nom mis dans la liste des thèmes. Ces fichiers contiendront du coup les variables ainsi que les couleurs css associé.

      Donc theme.js ne lira au départ que theme.json puis fera une boucle sur la liste pour charger les thèmes.

      Et là vient le localStorage qui est stockage persistant accessible via js

      si un theme existe dans le localstorage on affecte ses variables après le chargement des thèmes 

      ensuite au changement de thème il suffira de mettre à jour cette valeur dans le localStorage ( ça peut être le nom du fichier qui est censé être unique pour reconnaître le thème.

      Voila tout pour ce que je pouvais expliquer si besoin d'un exemple de code après avoir tenter ? 

      • Partager sur Facebook
      • Partager sur Twitter

      yasakani no magatama

        23 septembre 2022 à 7:50:57

        Bonjour,

        pour ma part je me suis inspirée pour mon site de l'article de Max Böck sur le sujet (la partie JS, aux 2/3 de l'article). Ça se base également sur du localStorage.

        • Partager sur Facebook
        • Partager sur Twitter

        Pas d'aide concernant le code par MP, le forum est là pour ça :)

          25 septembre 2022 à 12:53:26

          Merci beaucoup pour la fonction localStorage. J'ignorais qu'on pouvait faire du stockage avec du JS en natif. Cela simplifie tout !

          Je suppose que c'est ce que la plupart des sites professionnels utilisent (comme sur MDN, clubic...).

          Donc voici mon code JS :

                      let myBody = document.querySelector("body");
          
          
                      /**
                       * Charger thème au démarrage
                       */
                      function loadTheme() {
                          if (localStorage.getItem("theme") === null) { // Si aucun thème n'est encore enregistré dans localStorage :
                              
                              if (window.matchMedia) { // Détecter le thème du navigateur au démarrage :
          
                                  if (window.matchMedia("(prefers-color-scheme: dark)").matches) { // Sombre :
                                      var theme = "dark";
                                  }
                                  
                                  if (window.matchMedia("(prefers-color-scheme: light)").matches) { // Clair :
                                      var theme = "light";
                                  }
                              }
          
                              localStorage.setItem("theme", theme); // Ecriture
                              myBody.classList.add(theme); // Modification DOM
                          }
          
                          else { // Si un thème est déjà enregistré dans localStorage :
                              if (localStorage.getItem("theme") === "dark") {
                                  myBody.classList.add("dark");
                              }
                              else {
                                  myBody.classList.add("light");
                              }
                          }
                      }
          
          
                      /**
                       * Changer thème
                       */
                      function changeTheme() {
                          if (localStorage.getItem("theme") === "dark") {
                              localStorage.setItem("theme", "light"); // Ecriture
                              myBody.classList.remove("dark");
                              myBody.classList.add("light");
                          }
                          else {
                              localStorage.setItem("theme", "dark"); // Ecriture
                              myBody.classList.remove("light");
                              myBody.classList.add("dark");
                          }
                      }
          
          
                      loadTheme(); // Charger thème au démarrage
          
          
                      const btnDark = document.getElementById("btn_dark");
                      if (btnDark) {
                          btnDark.addEventListener("click", changeTheme); // Change le thème au clic
                      }


          Tout a l'air de fonctionner parfaitement maintenant, et sans erreur.

          Mais je n'ai pas utilisé json. C'est quoi l'avantage ?

          -
          Edité par Terry-Bogard 25 septembre 2022 à 13:29:09

          • Partager sur Facebook
          • Partager sur Twitter
            25 septembre 2022 à 13:07:17

            pour faire simplement un thème sombre / clair aucun quoique si

            pour faire du multi thème l'utilité est de pouvoir ajouter sans toucher au code un nouveau thème via une interface administrateur par exemple, le partage de thème sous un même format également 

            -
            Edité par zvheer 25 septembre 2022 à 13:07:29

            • Partager sur Facebook
            • Partager sur Twitter

            yasakani no magatama

            Changer Thème sombre-clair au clic

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            • Editeur
            • Markdown