Sebastian: Script für dynmaschischen Klassen-Austausch

Hallo,

ich arbeite gerade an einem Script,
das es ermöglichen soll, dynamisch das ClassName-Attribut
eines beliebigen Tags bei MouseOver zu verändern.

Ich habe mir das Script zusammengeschnippselt und weiß nicht, ob ich auf dem richitgen Weg bin. Ich habe nur rudimentäre JS-Kenntnisse.

Vielleicht kann mir jemand auf die Sprünge helfen:

sfHover = function() {

var all = document.getElementsByTagName('LI');
var allClass = new Array();
var re = "test";
for (var i=0; i<all.length; i++)
if (all[i].getAttribute('class').search(re) !=-1) {
allClass[allClass.length] = all[i];

all[i].onmouseover=function() {
   this.className+=" showtime";
   }
all[i].onmouseout=function() {
   this.className=this.className.replace(new RegExp(" showtime\b"), "");
   }
}
}

}
if (window.attachEvent) window.attachEvent("onload", sfHover);

Nochmal zur Erklärung:
Das Script soll alle LI-Tags durchsuchen und bei alleen, bei denen es ein Atribut class="test" gibt, dieses durch class="showtime" ersetzen.

Es geht hier um ein Suckerfish-CSS-Menü, dass im Internet Explorer nur mit JS funktioniert. Durch eine Kombination von verschiedenen Funktionalitäten halte ich diesen Lösungsansatz am praktikabelsten.
Außerdem denke ich, wenn das Script erstmal steht, lässt es sich für
andere Anwendungen leicht adaptieren.

Ich denke da zum Beispiel an ein Script, dass beliebige Objekte zeitgesteuert auf einer Seite einfadet. Dafür wäre der Zugriff auf beliebiege Tags und classNames sehr praktisch.

Schöne Grüße,
Sebastian

  1. Hallo Sebastian,

    Das Script soll alle LI-Tags durchsuchen und bei alleen, bei denen es ein Atribut class="test" gibt, dieses durch class="showtime" ersetzen.

    Du brauchst wahrscheinlich so etwas wie getElementsByClassName() von Thomas Meinicke.

    Gruß Gernot

    1. Gernot schrieb:

      Du brauchst wahrscheinlich so etwas wie getElementsByClassName() von Thomas Meinicke.

      Hallo Gernot,

      das sieht schon mal sehr gut aus.
      Ich werde das mal in Ruhe testen!

      Danke!

      Gruß,
      Sebastian

      1. Yipiehhhh!

        Ich hab's!
        http://www.zabdesign.de/pro/stahmann-medien/

        suckerFocus = function() {
        var sfEls = document.getElementsByTagName("LI");
        for (var i=0; i<sfEls.length; i++) {
          sfEls[i].onmouseover=function() {
           this.className+=" showtime";
          }
          sfEls[i].onmouseout=function() {
           this.className=this.className.replace(new RegExp(" showtime\b"), "");
          }
        }
        }
        if (window.attachEvent) window.attachEvent("onload", suckerFocus);

        greift nun auf folgenden HTML-Code zu:

        <li class="dynav"><a href="#" title="Aktuelle Meldungen"><dfn>2: </dfn>Aktuelles<span class="speakonly">. </span></a>
            <ul>
              <li><a href="#" title="">Dies ist ein Extranet</a></li>
              <li><a href="#" title="">Ich bin ein globales Netz</a></li>
              <li><a href="#" title="">Wir sind im Internet</a></li>
            </ul>

        Durch die Formate im CSS-Code wird nun bei Änderung des Klassenamens
        das Submenü eingeblendet!
        Ich kann jetzt beliebig viele Submenüs ausgeben und alle haben den gleichen Klassennamen.

        Ich glaube sauberer kann man es kaum lösen!
        Euch allen, Alistapart und HTMLDog sei Dank!

        Sonnige Grüße aus Bremen,
        Sebastian

    2. Hallo,

      ich habe jetzt mal folgende functionen in ein externes
      Script übernommmen, um das Ganze mal zu testen.

      function switchClass(klasse_alt,klasse_neu)
      {
        var obj=getElementsByClassName(klasse_alt);

      for(i=0;i<obj.length;i++)
        {
          obj[i].className=klasse_neu;
        }
      }

      function getElementsByClassName(class_name)
      {
        var all_obj,ret_obj=new Array(),j=0,teststr;

      if(document.all)all_obj=document.all;
        else if(document.getElementsByTagName && !document.all)
          all_obj=document.getElementsByTagName("*");

      for(i=0;i<all_obj.length;i++)
        {
          if(all_obj[i].className.indexOf(class_name)!=-1)
          {
            teststr=","+all_obj[i].className.split(" ").join(",")+",";
            if(teststr.indexOf(","+class_name+",")!=-1)
            {
              ret_obj[j]=all_obj[i];
              j++;
            }
          }
        }
        return ret_obj;
      }
      switchClass('test','bestanden');

      Quelle: http://www.styleassistant.de/tips/tip100.htm

      Bei mir tut sich da leider genau garnichts.
      Sieht vielleicht jemand was ich falsch gemacht habe.

      Ich komme absolut nicht weiter.

      Gruß,
      Sebastian

      1. Hallo,

        Quelle: http://www.styleassistant.de/tips/tip100.htm

        Bei mir tut sich da leider genau garnichts.

        Es gibt dazu auch ein Beispiel.

        MfG, Thomas

        1. Hallo Thomas,

          Es gibt dazu auch ein Beispiel.

          genau daher habe ich den Code!

          Gruß,
          Sebastian

          1. Hallo,

            Es gibt dazu auch ein Beispiel.

            genau daher habe ich den Code!

            Steht die Zeile
            switchClass('test','bestanden');
            auch so im externen Skript?

            Dann wird offenbar zu frueh auf die Klassen zugegriffen, d. h. diese sind im DOM-Baum noch gar nicht praesent.

            Versuche es mal so:
            <body onload="switchClass('test','bestanden')">

            MfG, Thomas

            1. Hallo Thomas,

              ich bin inzwischen durch Tipps und Hinweise bei einem anderen Lösungsansatz angelangt.

              Er funktioniert noch nicht, doch von der Idee her bin ich
              auf dem richtigen Weg ... denke ich!

              suckerFocus = function() {
              var sfEls = document.getElementsByTagName("LI");
              for (var i=0; i<sfEls.length; i++) {
                sfEls[i].onmouseover=function() {
                 this.className+="showit";
                }
                sfEls[i].onmouseout=function() {
                 this.className=this.className.replace(new RegExp("showit\b"), "");
                }
              }
              }
              if (window.attachEvent) window.attachEvent("onload", suckerFocus);

              Eigentlich würde ich gerne nur LI-Tags herausfiltern, die den Klassennamen "hideit" haben und den dann dynamisch ändern.
              Ich habe mich jetzt erstaml für die obige einfache Variante entschieden, da ich weiß, dass diese so ähnlich an anderer Stelle schon funktioniert.

              Die Klasse muss nur showtime heißen, damit diesen Style darauf anwenden kann.

              /* IE hover action */
              .showtime ul {left: auto;}

              Nur in meinem Fall funktioniert das noch nicht!
              http://www.zabdesign.de/pro/stahmann-medien/

              Gruß,
              Sebastian

      2. Hallo Sebastian,

        also in deinem Fall und bei näherer Betrachtung deiner Bedürfnisse kann ich mich eigentlich nur meinen Vorrednern anschließen.

        Was spricht denn gegen die in SEFHTML beschriebene Variante:

        http://de.selfhtml.org/css/layouts/navigationsleisten.htm#modern
        nebst der darunter stehenden Erweiterung für den IE?

        Das erscheint mir auch einfacher.

        Gruß Gernot

        1. Hallo Gernot,

          Was spricht denn gegen die in SEFHTML beschriebene Variante:
          http://de.selfhtml.org/css/layouts/navigationsleisten.htm#modern
          nebst der darunter stehenden Erweiterung für den IE?

          Das erscheint mir auch einfacher.

          Ich habe die JavaScript-Erweiterung jetzt erst entdeckt:

          <!--[if IE]><script type="text/javascript">
            function hoverIE() {
              var LI = document.getElementById("Navigation").firstChild;
              do {
                if(LI.firstChild) {  // A (SPAN)
                  if(LI.firstChild.nextSibling) {  // #text
                    if(LI.firstChild.nextSibling.nextSibling) {  // UL ?
                      LI.onmouseover=einblenden; LI.onmouseout=ausblenden;
                    }
                  }
                }
                LI = LI.nextSibling;
              }
              while(LI);
            }
            function einblenden() {
              this.firstChild.nextSibling.nextSibling.style.display = "block";
              this.firstChild.nextSibling.nextSibling.style.backgroundColor = "silver";
            }
            function ausblenden() {
              this.firstChild.nextSibling.nextSibling.style.display = "none";
            }
          window.onload=hoverIE;
          </script><![endif]-->

          Das sieht tatsächlich einfacher aus, auch wenn ich es noch nicht verstehe.

          Danke!

          Gruß,
          Sebastian

          1. Hi,

            das Script hjangelt sich durch's DOM, wie Du an den Kommentaren siehst.

            var LI = document.getElementById("Navigation").firstChild;

            das erste LI der UL mit der ID "Navigation".

            if(LI.firstChild) {  // A (SPAN)

            hierin enthaltenes A

            if(LI.firstChild.nextSibling) {  // #text

            und der Textknoten darin

            if(LI.firstChild.nextSibling.nextSibling) {  // UL ?

            folgt darauf ein weiteres Element? Das Script ist hier bewußt einfach gehalten und geht davon aus, daß es sich in diesem Fall nur um eine verschachtelte UL handeln kann.

            In Deinem Fall - mit nur einer ID - kannst Du Dir dieses Hangeln auch sparen und direkt über die ID auf das Element zugreifen. Diese Vereinfachung ginge natürlich auch mit einer zweiten ID "dynav2" etc.

            freundliche Grüße
            Ingo

            1. Hallo Ingo,

              danke für die Erklärung.
              Ich habe inzwischen soviele Lösungsansätze,
              dass ich garnicht mehr weiß, wo vorn und hinten ist.

              Dazu scheint draußen so sehr die Sonne,
              dass ich glaube ich erstmal die Bestrahlung mit natürlichem
              Licht, dem Monitor vorziehe.

              Vielleicht kommt die Lösung dann fast wie von selbst!

              Danke!

              Gruß,
              Sebastian

  2. Hi,

    Das Script soll alle LI-Tags durchsuchen und bei alleen, bei denen es ein Atribut class="test" gibt, dieses durch class="showtime" ersetzen.

    wenn Du ohnehin eine wie ich annehme verschachtelte Liste verwendest, warum willst Du den Quelltext dann mit überflüssigen Klassen verunstalten?
    Da finde ich eine Lösung wie im Beispiel http://de.selfhtml.org/css/layouts/navigationsleisten.htm#javascript - evtl. auch universeller geschrieben - schon sinnvoller.

    Außerdem denke ich, wenn das Script erstmal steht, lässt es sich für
    andere Anwendungen leicht adaptieren.

    Für andere Zwecke mag es durchaus sinnvoll sein, müßte dann aber für alle Browser funktionieren.

    freundliche Grüße
    Ingo

    1. Ingos schreib:

      wenn Du ohnehin eine wie ich annehme verschachtelte Liste verwendest, warum willst Du den Quelltext dann mit überflüssigen Klassen verunstalten?

      Hallo Ingo,

      das mit den Klassen ist schon eine durchdachte Sache!

      Es handelt sich um ein Menü das zwei unterschiedliche Techniken miteinander kombiniert!

      <www.zabdesign.de/pro/stahmann-medien/>

      Das ganze ist wirklich kniffelig, denn es gibt zwei Arten von verschachtelten Listen. Zur Zeit habe ich eine id="dynav" in
      Verwendung um für alle inaktiven Menüpunkte, die Unterpunkte haben,
      ein Flyout anzuzeigen.
      Das Problem mit der id ist, dass man Sie - streng genommen - nur einmal verwenden darf.

      Will ich also mehrere Menüpunkte mit einem "dynamischen" Untermenü versehen, brauche ich Klassen.

      Da ich den Code nicht mit unnötigen Scriptanweisungen verunstalten will  ;-) möchte ich ein kleines Script benutzen, dass eben dynamisch meine gewünschte Klasse erzeugt, um das Menü bei mouseover anzuzeigen.
      Eine feine Sache, wenn es erstmal fertig ist!

      Ich gebe zu, dass meine Idee bis jetzt nicht gerade offensichtlich war, von daher kann ich deinen "Einwand" verstehen.

      Freundliche Grüße sendet dir Sebastian

      1. hi,

        das mit den Klassen ist schon eine durchdachte Sache!

        sehe ich anders.

        Das Problem mit der id ist, dass man Sie - streng genommen - nur einmal verwenden darf.

        nicht "streng" oder "weniger streng" genommen - sondern _absolut_ nur ein mal.

        Will ich also mehrere Menüpunkte mit einem "dynamischen" Untermenü versehen, brauche ich Klassen.

        nein, nicht unbedingt - zumindest nicht in dem ausmaß, wie du das hier skizzierst.

        Da ich den Code nicht mit unnötigen Scriptanweisungen verunstalten will  ;-) möchte ich ein kleines Script benutzen, dass eben dynamisch meine gewünschte Klasse erzeugt, um das Menü bei mouseover anzuzeigen.

        du bräuchtest eigentlich nur an dem einen menüpunkt, der das untermenü "ausfahren" soll, eine veränderung vornehmen. beispielsweise diesem eine klasse geben - so dass alle darunter liegenden untermenüpunkte dann anders formatiert werden. das machst du aber sehr viel einfacher mit dem nachfahrenselektor, als in dem du jedem dieser untermenüpunkte dynamisch eine andere klasse aufdrückst.

        Eine feine Sache, wenn es erstmal fertig ist!

        aber nur, wenn du es nicht zu umständlich machst.
        und auch nur, wenn du dafür sorgst, dass es ohne javascript komplett nutzbar bleibt - also per default erst mal alles ausgeklappt lassen, und dann ggf. beim laden der seite per JS die untermenüs zunächst wieder einklappen.

        gruß,
        wahsaga

        --
        /voodoo.css:
        #GeorgeWBush { position:absolute; bottom:-6ft; }
        1. Hallo wahsaga,

          das mit den Klassen ist schon eine durchdachte Sache!

          sehe ich anders.

          Es ist durchdacht! Das kannst du sehen wie du willst! ;-)

          Das Problem mit der id ist, dass man Sie - streng genommen - nur einmal verwenden darf.

          nicht "streng" oder "weniger streng" genommen - sondern _absolut_ nur ein mal.

          Ja, du hast recht! ... und das das Haar genau in der Mitte gespalten! ;-)

          Will ich also mehrere Menüpunkte mit einem "dynamischen" Untermenü versehen, brauche ich Klassen.

          nein, nicht unbedingt - zumindest nicht in dem ausmaß, wie du das hier skizzierst.

          Ok, wie du meinst!

          du bräuchtest eigentlich nur an dem einen menüpunkt, der das untermenü "ausfahren" soll, eine veränderung vornehmen. beispielsweise diesem eine klasse geben - so dass alle darunter liegenden untermenüpunkte dann anders formatiert werden. das machst du aber sehr viel einfacher mit dem nachfahrenselektor, als in dem du jedem dieser untermenüpunkte dynamisch eine andere klasse aufdrückst.

          Ja, es könnte in der Tat eine einfachere Lösung geben.
          Ich kann allerdings nur auf dem Niveau operirieren, das meinem
          Wissenstand angemessen ist und Dinge von denen ich noch weniger
          verstehe, als von dem was ich zur Zeit ausprobiere, sind für mich erstmal nicht praktikabel, denn ich will ja nicht 3 Tage und 3 Nächte an der Lösung sitzen.
          Wenn dann im Endeffekt drei Zeilen Code mehr dabei herauskommen als eigentlich notwendig, ist mir dass eigentlich egal.

          Über Hilfe freue ich mich natürlich!

          Eine feine Sache, wenn es erstmal fertig ist!

          aber nur, wenn du es nicht zu umständlich machst.

          Mal schauen.
          Eine Fallbacklösung wird es nicht geben,
          denn jemand ohne JS wird die extra Menüpunkte nur dann sehen,
          wenn der Punkt im Menü aktiv ist. (wie jetzt bei Referenzen) Ansonsten wäre das Menü ja immer
          komplett ausgefahren und das macht in meinen Augen nicht wirklich Sinn.

          Gruß,
          Sebastian

      2. Hi,

        Es handelt sich um ein Menü das zwei unterschiedliche Techniken miteinander kombiniert!

        <www.zabdesign.de/pro/stahmann-medien/>

        Das ganze ist wirklich kniffelig, denn es gibt zwei Arten von verschachtelten Listen. Zur Zeit habe ich eine id="dynav" in
        Verwendung um für alle inaktiven Menüpunkte, die Unterpunkte haben,
        ein Flyout anzuzeigen.

        Du machst es Dir selbst knifflig.
        Gebe den dynamischen LIs eine Klasse "dynav" (wenn's auch mehrere sein können) und erweitere das Script auf der genannten Selfhtml-Seite dahingehend, daß auf diese Klasse geprüft wird. Fertig. Ganz ohne Javascript für nicht-IEs.
        Momentan - nur mit einem dynamischen Listenpunkt - wäre es mit dieser Methode sogar noch viel einfacher.

        freundliche Grüße
        Ingo

        1. Hallo Ingo,

          vielen Dank für deinen Tipp:

          Gebe den dynamischen LIs eine Klasse "dynav" (wenn's auch mehrere sein können) und erweitere das Script auf der genannten Selfhtml-Seite dahingehend, daß auf diese Klasse geprüft wird. Fertig. Ganz ohne Javascript für nicht-IEs.

          ... doch das kriege ich nicht hin! Ich habe zu wenig Ahnung von
          JavaScript.

          Gruß,
          Sebastian

          1. Hi,

            Gebe den dynamischen LIs eine Klasse "dynav" (wenn's auch mehrere sein können) und erweitere das Script auf der genannten Selfhtml-Seite dahingehend, daß auf diese Klasse geprüft wird. Fertig. Ganz ohne Javascript für nicht-IEs.

            ... doch das kriege ich nicht hin! Ich habe zu wenig Ahnung von
            JavaScript.

            ach das ist doch sowas von einfach:

            ...

              
                do {  
                  if (LI.className == "dynav") {  
                    if(LI.firstChild) {  // A  
                      if(LI.firstChild.nextSibling) {  // #text  
                        if(LI.firstChild.nextSibling.nextSibling) {  // UL  
                          LI.onmouseover=einblenden; LI.onmouseout=ausblenden;  
                        }  
                      }  
                    }  
                  }  
                  LI = LI.nextSibling;  
                }  
            
            

            ...

            freundliche Grüße
            Ingo

            1. Hallo Ingo,

              ich danke dir für deine Bemühungen!
              Ich habe es inzwischen einfacher gelöst.
              Du kannst es dir ja mal anschauen:
              http://www.zabdesign.de/pro/stahmann-medien/

              Freundliche Grüße,
              Sebastian

              1. Hi,

                Ich habe es inzwischen einfacher gelöst.
                Du kannst es dir ja mal anschauen:
                http://www.zabdesign.de/pro/stahmann-medien/

                habe ich mir jetzt zwar nicht ganz genau angesehen, aber in meinem IE 6 tut sich auch bei Klick auf "extras" nichts (wobei ich ausnahmsweise mal JS und ActiveX zugelassen habe).

                freundliche Grüße
                Ingo