Peter: Klassenerweiterung eines Java-Script

Hab hier ein kleines Modell des eigentlichen Problems. Das Problem eigentliche Problem bei der Sache ist dass ich die drei Abschnitte getrennt voneinander steuern möchte.

Also ich erklärs mal so:
Ich habe eine Übersichtsseite mit mehreren Diagrammen (ca.15) welche unterhalb der Links sind und durch betätigen der Links verändert sich die Ansicht des Diagramms. Was durch die Farbgebung der einzelnen Links verdeutlicht werden sollte. Deswegen ist auch in diesem Beispiel schon von Start an der erste rot hinterlegt.
Und immer wenn ich ein anderes anwähle soll natürlich dieses rot hinterlegt werden.

Nur ist es momentan so, dass es lediglich für ein einziges Diagramm funktionieren würde, da ich die Abschnitte bzw. Diagramme in Klassen einteilen muss damit richtig funktioniert!

Hoffe das ist nach dem zweitenmal durchlesen verständlich  ;)

<html>  
<head>  
<title>Unbenannt</title>  
  
<style type="text/css">  
<!--  
a {  
 font-family: Verdana, Arial;  
         color: #000000;  
         text-decoration: none;  
          background-color: #EEEEEE;  
}  
-->  
</style>  
  
<script type="text/javascript">  
  function save(sav)  
  {  
    document.getElementsByName('peter')[0].value = sav;  
  }  
  function CChange(name)  
  {  
    id = name;  
    document.getElementById(id).style.color = "#FFFFFF"; /* farbe des letzten inks */  
    document.getElementById(id).style.backgroundColor = "#AA00AA"; /* Hintergrundfarbe des letzten inks */  
    save(id);  
  }  
  function load(id)  
  {  
    vall = document.getElementsByName('peter')[0].value;  
    document.getElementById(vall).style.color = "#000000"; /* normale link-farbe */  
    document.getElementById(vall).style.backgroundColor = "#EEEEEE"; /* normale link-Hintergrundfarbe */  
    CChange(id);  
  }  
  
    function red()  
    {  
      document.getElementById('link1').style.color = "#FFFFFF";  
      document.getElementById('link1').style.backgroundColor = "#AA00AA";  
  
      document.getElementById('link4').style.color = "#FFFFFF";  
      document.getElementById('link4').style.backgroundColor = "#AA00AA";  
  
      document.getElementById('link7').style.color = "#FFFFFF";  
      document.getElementById('link7').style.backgroundColor = "#AA00AA";  
    }  
</script>  
  
</head>  
  
<body onload="javascript:red()">  
  
  
<input type="hidden" name="peter" value="link1">  
  
<a href="#" onclick="javascript:load(this.id)" id="link1">bla 1</a>  
<br><br>  
<a href="#" onclick="javascript:load(this.id)" id="link2">blö 1</a>  
<br><br>  
<a href="#" onclick="javascript:load(this.id)" id="link3">blub 1</a>  
  
  
<br><br><br><br><br>  
  
  
<a href="#" onclick="javascript:load(this.id)" id="link4">bla 2</a>  
<br><br>  
<a href="#" onclick="javascript:load(this.id)" id="link5">blö 2</a>  
<br><br>  
<a href="#" onclick="javascript:load(this.id)" id="link6">blub 2</a>  
  
  
<br><br><br><br><br>  
  
  
<a href="#" onclick="javascript:load(this.id)" id="link7">bla 3</a>  
<br><br>  
<a href="#" onclick="javascript:load(this.id)" id="link8">blö 3</a>  
<br><br>  
<a href="#" onclick="javascript:load(this.id)" id="link9">blub 3</a>  
  
</body>  
</html>
  1. Hallo,

    Ich würde das so lösen:

    <script type="text/javascript" src="http://dean.edwards.name/base/forEach.js"></script>  
    <script type="text/javascript">  
    [code lang=javascript]function init () {  
     forEach(  
      document.getElementsByTagName("ul"),  
      function (ul_element) {  
       forEach(  
        ul_element.getElementsByTagName("button"),  
        function (button_element) {  
         button_element.correspondingList = ul_element;  
         button_element.onclick = activate;  
        }  
       );  
      }  
     );  
    }  
    window.onload = init;  
    function activate () {  
     if (this.correspondingList.activeButton) {  
      this.correspondingList.activeButton.className = "";  
     }  
     this.className = "active";  
     this.correspondingList.activeButton = this;  
    }
    

    </script>
    <style type="text/css">

    button.active { color:red; }  
    ul, li { list-style-type:none; margin-left:0; padding-left:0; }
    

    </style>

    <ul>
    <li><button>Link 1</button></li>
    <li><button>Link 2</button></li>
    <li><button>Link 3</button></li>
    </ul>

    <ul>
    <li><button>Link 1</button></li>
    <li><button>Link 2</button></li>
    <li><button>Link 3</button></li>
    </ul>

    <ul>
    <li><button>Link 1</button></li>
    <li><button>Link 2</button></li>
    <li><button>Link 3</button></li>
    </ul>[/code]

    Erst einmal lage ich die JavaScript-Logik aus. Im HTML definiere ich lediglich drei Listen mit Buttons.

    Beim fertigen Laden wird eine Funktion gestartet, die alle Listen des Dokuments durchläuft und darin alle Buttons. Jedem Button gibt sie einen onclick-Handler und speichert zudem eine Referenz auf die zugehörige Liste als Eigenschaft am button-Elementobjekt. (Man kann in JavaScript jedem Objekt Eigenschaften anhängen. So kann man bequem direkt am Element eine Referenz auf das ul-Elementobjekt speichern, die man in der Event-Handler-Funktion ebenso bequem benutzen kann.)

    Um die Listen mit Elementknoten einfach zu durchlaufen, die document.getElementsByTagName zurückgibt, nutze ich eine externe Funktion namens forEach aus http://dean.edwards.name/base/forEach.js. Die sorgt einfach dafür, dass für jedes Element in der Liste die notierten anonymen Funktioen ausgeführt werden. Man kann aber auch einfach mit simplen verschachtelten for-Schleifen arbeiten, aber der Code wird dadurch schnell sehr lang und unübersichtlich. (Es gibt noch weitere Funktionssammlungen, die einem das Vergeben von Event-Handlern an bestimmte Elemente im Dokument noch besser vereinfachen, z.B. jQuery. Das aber nur am Rande.)

    Beim Klicken auf einen Button startet die Funktion activate. Die greift über this auf das button-Elementobjekt zu, bei dem der click-Event passierte. Daran hängt ja die Eigenschaft correspondingList, welche auf das zugehörige ul-Elementobjekt verweist. Wenn also an diesem Objekt eine Eigenschaft activeButton existiert, dann setze deren Eigenschaft className.

    Das ergibt Sinn, wenn man den Rest der Funktion activate betrachtet: Darin wird die Klasse auf aktice gesetzt und danach eine Eigenschaft namens activeButton am ul-Elementobjekt angelegt. Darin wird eine Referenz auf das gerade aktivierte button-Elementobjekt gespeichert. Am Anfang der Funktion wird also die Klasse dieses zuletzt aktivierten Buttons zurückgesetzt.

    Mathias

  2. hab's schon, wen's interessiert:

      
    <html>  
    <head>  
    <title>Unbenannt</title>  
      
    <style type="text/css">  
    <!--  
    a {  
       font-family: Verdana, Arial;  
       text-decoration: none;  
    }  
      
    .diagrammOn {  
       color: #FFFFFF;  
       background-color: #AA00AA;  
    }  
      
    .diagrammOff {  
       color: #000000;  
       background-color: #EEEEEE;  
    }  
      
    -->  
    </style>  
      
      
    <script type="text/javascript">  
      
    // Anzahl der Links pro Gruppe  
    var linkCount = 3  
      
    function changeClass(wo, gruppe) {  
       // Alle Links in der Gruppe zurücksetzen  
       for(i = 1; i <= linkCount; i++) {  
          if(document.getElementById("link_"+gruppe+"_"+i))  
             document.getElementById("link_"+gruppe+"_"+i).className = "diagrammOff";  
       }  
       // Ausgewählter Link  
       wo.className = "diagrammOn";  
    }  
      
    </script>  
      
    </head>  
      
    <body>  
      
      
    <a href="#" class="diagrammOn" onclick="changeClass(this,'a')" id="link_a_1">bla 1</a>  
    <br><br>  
    <a href="#" class="diagrammOff" onclick="changeClass(this,'a')" id="link_a_2">blö 1</a>  
    <br><br>  
    <a href="#" class="diagrammOff" onclick="javascript:changeClass(this,'a')" id="link_a_3">blub 1</a>  
    <br><br>  
      
      
      
    <br><br><br><br><br>  
      
      
    <a href="#" class="diagrammOn" onclick="changeClass(this,'b')" id="link_b_1">bla 2</a>  
    <br><br>  
    <a href="#" class="diagrammOff" onclick="changeClass(this,'b')" id="link_b_2">blö 2</a>  
    <br><br>  
    <a href="#" class="diagrammOff" onclick="changeClass(this,'b')" id="link_b_3">blub 2</a>  
      
      
    <br><br><br><br><br>  
      
      
    <a href="#" class="diagrammOn" onclick="changeClass(this,'c')" id="link_c_1">bla 3</a>  
    <br><br>  
    <a href="#" class="diagrammOff" onclick="changeClass(this,'c')" id="link_c_2">blö 3</a>  
    <br><br>  
    <a href="#" class="diagrammOff" onclick="changeClass(this,'c')" id="link_c_3">blub 3</a>  
      
    </body>  
    </html>
    
  3. Ja aber ich denke so wie ich es gemacht hab ist es sogar einfacher, oder ist das unsauberer Programmierstil?

    Weil bei dem von dir genannten müsste ich dann noch etwas verändern...

    1. Hallo,

      Ja aber ich denke so wie ich es gemacht hab ist es sogar einfacher

      Finde ich nicht. Du musst ewig viel immer gleichen Code ins HTML schreiben, nur damit die JavaScript-Operationen »einfach« bleiben. Da würde ich lieber etwas fortgeschrittenen JavaScript-Code benutzen, anstatt den HTML-Code aufzublähen.

      oder ist das unsauberer Programmierstil?

      Ja, das auch. Vor allem ist es für dich unübersichtlich, schlecht wartbar und schlecht ausbaubar, wenn du JavaScript-Logik direkt im HTML unterbringst. Beschäftige dich mal mit den Vorteilen von »Unobtrusive JavaScript«. Siehe auch http://aktuell.de.selfhtml.org/weblog/javascript-einsatz.

      Weil bei dem von dir genannten müsste ich dann noch etwas verändern...

      Das solltest du sowieso, die Benutzung von hunderten <br> ist keine sinnvolle Textauszeichnung. Du kannst ein paar div-Elemente oder wie gesagt ul-Listen verwenden, um die Elemente zu strukturieren. Die lassen sich auch viel besser mit CSS adressieren und formatieren. <br><br><br> usw. ist ein Codestil, den man vor 10 Jahren geschrieben hat...

      Wenn du die JavaScript-Logik automatisch hinzufügst, bleibt dir einiges erspart: Dann brauchst nicht jedem Link eine ID vergeben, wenn zusammengehörige Elemente in einem gemeinsamen Container-Element liegen. Du musst nicht alle Links durchlaufen und deren Klasse zurücksetzen, sondern kannst gezielt das letzte aktive Element zurücksetzen. Das heißt auch, dass die Anzahl der Links pro Gruppe nicht festgelegt werden muss. Und natürlich musst du nicht onclick="changeClass(this, 'gruppenname')" notieren.

      Das kann JavaScript alles automatisch machen - diese Möglichkeiten sollte man früher oder später kennenlernen, wenn man mit JavaScript etwas sinnvolles anfangen will.

      Mathias