einsiedler: mit java-script class ändern

Hallo liebe Forumer,

ich brauche eure Unterstützung. Folgende Ausgangssituation, ich möchte per java script eine class ändern und zwar möchte ich es nutzen als switch wenn java-script deaktiviert ist:

mein css:

.js-enabled [aria-expanded="false"] + .nav-group { display:none !important;}

.js-disabled [aria-expanded="false"] + .nav-group { display:block !important;}

<li class="treespanmain js-disabled" role="treeitem">

<button aria-expanded="false"><span class="visually-hidden">HauptNavigation</span></button>

[ ... ] .... and so on …

dabei möchte ich aus der classe für das li {treespanmain js-enabled} machen

Bisher habe ich folgendes ausprobiert:

<script>
		// <botton> die Klasse "js-enabled" geben
		function init() {
			document.li.className = "js-disabled";
			document.li.remove("js-enabled");
		};
		
		function globalClickManager(ev){
			// ev.target gibt uns das Element auf dem der Click geschah.

			// steuere expanded Buttons
			if(ev.target.hasAttribute("aria-expanded") ){
				ev.target.setAttribute("aria-expanded", ( ev.target.getAttribute("aria-expanded") == "false") ); 
			}
			// Buttons die lediglich den Click transferieren ähnlich zu label Elementen
			else if(ev.target.hasAttribute("data-for-id") ){
				document.getElementById( ev.target.getAttribute("data-for-id") ).click();
			}
			else if( Element.prototype.closest){
				if( ev.target.closest("nav") == null ){
					var temp = document.querySelector("nav [aria-expanded='true']");
					if(temp) temp.setAttribute("aria-expanded","false");
				}
			}
		}
[and so on] ...

ABER bei mir funktioniert das nicht, auch wenn java-script aktiviert ist bleibt das js-disabled stehen und wechselt NICHT!

Was mache ich falsch?

der einsiedelnde

  1. Hallo,

    <li class="treespanmain js-disabled" role="treeitem">

      	document.li.className = "js-disabled";
      	document.li.remove("js-enabled");
    

    schau dir mal

    https://wiki.selfhtml.org/wiki/JavaScript/DOM/Element/classList
    https://wiki.selfhtml.org/wiki/JavaScript/DOM/Document/querySelector

    und

    https://wiki.selfhtml.org/wiki/JavaScript/DOM/Document/querySelectorAll

    an.

    Gruß
    Jürgen

    1. Nicht brauchbar! :o((

      Der botton soll nichts damit zu tun haben, nur eine schlichte class-änderung

      1. Hallo,

        Nicht brauchbar! :o((

        was? Dein von mir zitierter Code oder meine Tipps?

        Der botton soll nichts damit zu tun haben, nur eine schlichte class-änderung

        verstehe ich nicht.

        Gruß
        Jürgen

  2. hallo

    mein css:

    .js-enabled [aria-expanded="false"] + .nav-group { display:none !important;}

    .js-disabled [aria-expanded="false"] + .nav-group { display:block !important;}

    nimm das

    <noscript><link rel="stylesheet" href="nojs.css"></noscript>

    1. Nicht brauchbar!

      1. hallo

        Nicht brauchbar!

        warum nicht?

        1. funktioniert irgendwie nicht da er die angaben des anderen css irgendwie nicht überschreibt

          1. hallo

            funktioniert irgendwie nicht da er die angaben des anderen css irgendwie nicht überschreibt

            Wenn du das noscript.css nach deinem standard.css einbindest, sollte die gleiche Spezifität der Selektoren bereits reichen.

  3. @@einsiedler

    .js-disabled [aria-expanded="false"] + .nav-group { display:block !important;}

    Hier steckt dein erster Fehler. Das aria-expanded-Attribut gibt an, dass das Ding nicht zu sehen sein soll. Das Stylesheet gibt an, dass das Ding doch zu sehen sein soll.

    Den Widerspruch musst du als erstes lösen. Wenn JavaScript nicht läuft, darf das aria-expanded-Attribut gar nicht auf "false" gesetzt sein.

    LLAP 🖖

    --
    „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
    1. .js-enabled [aria-expanded="false"] + .nav-group { display:none !important;}

      .js-disabled [aria-expanded="false"] + .nav-group { display:block !important;}

      Zwischen diesen beiden classes möchte ich umzwitschen wenn java-script aktiviert == [aria-expanded="false"] + .nav-group { display:none !important;}

      ABER

      wenn java-script deaktiviert == [aria-expanded="false"] + .nav-group { display:block !important;}

      und zwar damit das das li

      <li class="treespanmain js-disabled" role="treeitem">

      die zwei classes treespanmain UND js-disabled bzw js-enabled erhält

      der ratlose einsiedelnde der auf eine schnelle antwort hofft

      1. @@einsiedler

        .js-enabled [aria-expanded="false"] + .nav-group { display:none !important;}

        .js-disabled [aria-expanded="false"] + .nav-group { display:block !important;}

        Zwischen diesen beiden classes möchte ich umzwitschen

        Nei-en. Letzteres ist wohl grundverkehrt, wenn .navgroup sichtbar ist, aber das aria-expanded-Attribut des zugehörigen Buttons angibt, dass es nicht sichtbar ist. Das dürfte etliche Screenreader-Nutzer verwirren.

        Wenn JavaScript nicht ausgeführt wird, sollte das aria-expanded-Attribut nicht den Wert "false" haben, sondern "undefined". [WAI-ARIA] Oder gar nicht vorhanden sein. Das hieße also: aria-expanded erst mit JavaScript auf "true" setzen.

        Allerdings sind die Buttons, wenn JavaScript nicht ausgeführt wird, ohne Funktion. Dann sollten sie aber gar nicht zu sehen sein: <button hidden="">. (Wenn die Buttons hidden sind, könnten sie auch aria-expanded="true" haben.) Mit JavaScript wird das hidden-Attribut entfernt.

        Oder die Buttons werden mit CSS display: none ausgeblendet (und wenn JavaScript läuft, eingeblendet).

        Was du nicht brauchst: zwei Klassen js-enabled und js-disabled. Eine reicht. Mit JavaScript setzst du js-enabled. Ohne JavaScript ist die Klasse nicht da.

        .js-enabled [aria-expanded="false"] + .nav-group { display:none !important;} wie gehabt. Die andere Regel brauchst du nicht.

        LLAP 🖖

        --
        „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
        1. hallo

          Was du nicht brauchst: zwei Klassen js-enabled und js-disabled. Eine reicht. Mit JavaScript setzst du js-enabled. Ohne JavaScript ist die Klasse nicht da.

          Keine reicht noch viel mehr.

        2. DANKE, DAS bringt mich weiter. morgen mehr!

          Gute n8 der einsiedelnde

  4. wenn ich

    var classchange = document.querySelector("#treespanmain");

    classchange.classList.add("js-enabled");

    benutze bei

    <li id="treespanmain" class="treespanmain" role="treeitem">

    funktioniert es.

    Aber die class js-enabled ist im dev-tool nicht sichtbar, womöglich da ja noch die classe .treespanmail dort steht, die ich aber auch benötige.

    Also wie füge ich eine zweite classe dort ein wenn schon eine besteht?

    1. Hallo einsiedler,

      wenn wir nochmal bei der Klasse bleiben: ein Element <li class="treespanmain js-disabled">

      kannst Du mit var classchange = document.querySelector(".treespanmain"); finden. Dafür brauchst Du die Klasse nicht in eine id umzuwandeln (was in deinem CSS ja möglicherweise Folgen haben könnte).

      Ein class Selektor prüft: Ist diese Klasse in der Klassenliste des Elements enthalten. D.h. Du kannst nach .treespanmain suchen, auch wenn das li noch 17 andere Klassen hätte.

      Aber wie auch immer. Über queryElementById() kommst Du ja auch dran, wenn Du es wie von Dir gezeigt änderst.

      Wenn Du das DOM-Objekt dann am Wickel hast, dann kannst Du über classList.add eine Klasse hinzufügen. Oder mit remove entfernen. Das hast Du völlig richtig gemacht.

      Aber dann. Wo hast Du dann in den Dev-Tools geschaut? Im Source oder im DOM? Das sind zwei verschiedene Tabs - die Source-Ansicht zeigt das, was vom Server kommt und die DOM Ansicht zeigt das, was dein JavaScript draus gemacht hat. Die DOM-Ansicht heißt in Firefox "Inspektor", in Chrome "Elements", in Edge "Elemente" und im IE "DOM Explorer". Die geänderte classList siehst Du NUR im DOM.

      Rolf

      --
      sumpsi - posui - clusi
      1. ich habe nun

        document.getElementById(".treespanmain").className = document.getElementById(".treespanmain").className.replace ( /(?:^|\s).js-disabled(?!\S)/g , '.js-enabled' )
        

        aber das funktioniert nicht :o(

        1. @@einsiedler

          ich habe nun

          document.getElementById(".treespanmain").className = document.getElementById(".treespanmain").className.replace ( /(?:^|\s).js-disabled(?!\S)/g , '.js-enabled' )
          

          zwei Probleme.

          LLAP 🖖

          --
          „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
          1. Wie lautet es richtig?

            1. @@einsiedler

              Wie lautet es richtig?

              Welche Fragen lässt MDN: classList diesbezüglich offen?

              LLAP 🖖

              --
              „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
        2. Hallo einsiedler,

          warum gehst du von classList weg? Diese Eigenschaft ist genau dazu da, um den Jurassic Park des Tyrannosaurus Regex nicht betreten zu müssen.

          Rolf

          --
          sumpsi - posui - clusi
          1. Das hat bei mir als einzigstes funktioniert. Eine andere lösung wäre mir auch recht, aber dann bitte genau zeigen wie.

            1. Hallo einsiedler,

              was soll ich zeigen? Du hattest es doch selbst schon richtig, mit classList.add(...). Wenn das nicht funktioniert hat, lag das an einer Ursache, die aus dem, was Du gezeigt hast, nicht erkennbar ist.

              Typische Probleme sind DOM Elemente, die nicht gefunden werden. Das führt meistens zu Fehlermeldungen im Konsole-Tab der Dev-Tools. Gab es welche?

              <exkurs thema="Deine Regex">
              /(?:^\|\s).js-disabled(?!\\S)/. Die matcht zu viel, und das falsche.

              • Deine einleitende Gruppe matcht den String-Anfang oder ein Whitespace. Das ist am String-Anfang okay, aber in "treemain js-disabled" würdest Du auch das Space zwischen den Klassennamen matchen und ersetzen. Das willst Du nicht.
              • Der Punkt gehört da nicht hin. Aus zwei Gründen
                • In einem CSS Selektor bedeutet der Punkt, dass jetzt ein Klassenname folgt. Der Punkt ist aber nicht Teil des className-Attributs, darum musst Du ihn auch nicht matchen.
                • Der Punkt hat in der Regex die Bedeutung, die bei der Dateisuche das Sternchen hat. Er matcht jedes Zeichen. Willst Du einen PUNKT matchen, musst Du ihn mit einem \ escapen. Aber wie gesagt, er gehört hier nicht hin.
              • Die Gruppe am Ende ist eine assertion-Group und würde sicherstellen, dass da nicht `js-disabledino' steht. Das ist ok, geht aber einfacher.

              Was Du gebraucht hättest, wäre /\bjs-enabled\b/g. \b steht für Word Boundary, damit findet man Worte.

              Zum Testen und Verstehen von Regex Mustern empfehle ich Dir https://regex101.com/. Der unterstützt die Regex-Formate verschiedener Sprachen (links einstellen). Du kannst probieren, ob dein Pattern das findest, was Du finden möchtest, und er erklärt Dir dein Pattern. Damit kannst Du abgleichen, ob dein Verständnis des Patterns mit dem übereinstimmt, was die Regex-Engine herausliest.
              </exkurs>

              Rolf

              --
              sumpsi - posui - clusi
              1. @@Rolf B

                Was Du gebraucht hättest, wäre /\bjs-enabled\b/g.

                Abgesehen davon, dass du /\bjs-disabled\b/g meintest …

                \b steht für Word Boundary, damit findet man Worte.

                Das ist ein Mythos.

                replace(/\bjs-disabled\b/g, 'js-enabled')
                ändert class="js-disabled nojs-disabled nöjs-disabled"
                in class="js-enabled nojs-disabled nöjs-enabled".

                js-disabled in js-enabled ist OK.

                nojs-disabled bleibt so – auch OK.

                nöjs-disabled wird auch geändert, weil ö als boundary zählt. Nicht OK.

                LLAP 🖖

                --
                „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
                1. Hi,

                  nöjs-disabled wird auch geändert, weil ö als boundary zählt.

                  Wirklich? Ich hätte gesagt, die Stelle zwischen ö und j ist die boundary, weil das ö als nicht-Wort-Zeichen gilt und das j schon.

                  Das \b matcht m.W. kein Zeichen.

                  cu,
                  Andreas a/k/a MudGuard

          2. hallo

            Hallo einsiedler,

            warum gehst du von classList weg?

            Weil es mit noscript eine Javascript-Unabhängig Lösung gibt!

        3. @@einsiedler

          document.getElementById(".treespanmain").className = document.getElementById(".treespanmain").className.replace ( /(?:^|\s).js-disabled(?!\S)/g , '.js-enabled' )
          

          aber das funktioniert nicht :o(

          Kann auch nicht. Du hast kein Element mit der ID .treespanmain. Mind the dot.

          document.getElementById(".treespanmain") ist also null. Genau das müsste dir die Konsole auch gesagt haben. Oder ist das Forum hier dein Debugger?

          LLAP 🖖

          --
          „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann