# onclick li Farbe ändern



## lahau (25. April 2011)

Hey,

hier mein HTML-Script:

```
<ul>
    <li style="background-color: Red" id="li1"><a id="1" href="1.html">1</a></li>
    <li style="background-color: Red" id="li2"><a id="2" href="2.html">2</a></li>
    <li style="background-color: Red" id="li3"><a id="3" href="3.html">3</a></li>
```

nun möchte ich das wenn man auf irgendeinen link z.b. 2 Klickt, das sich die Hintergrundsfarbe von dem li in welchem sich der link befindet li2 verändert.

Klicke ich aber danach auf einen anderen link z.b. 3, soll li2 wieder seine Ursprungs Farbe annehmen und sich das li verfärbe in welchem der neu angeklickte link sich befindet.

Ich bin schon soweit gekommen das ich erfahren habe das man dies mit onClick machen kann.

Es ist kein problem das ich die ganzen ids in den script dann rein schreibe. anders wird es denke ich auch nicht gehen.

Danke schon mal


----------



## CPoly (25. April 2011)

Ich hab das mal eben getippt und kommentiert. Aber bitte übernimm es nicht einfach, sondern guck es dir genau an und frag evtl. noch mal nach.


```
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
	<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
	
	<title>Listenfarbe</title>
	
	<style type="text/css">
		#list > li {
			background-color:red;
		}
	</style>
</head>

<body>
	<div>
		<ul id="list">
			<li>Foobar</li>
			<li>Foobar</li>
			<li>Foobar</li>
			<li>Foobar</li>
			<li>Foobar</li>
			<li>Foobar</li>
			<li>Foobar</li>
			<li>Foobar</li>
		</ul>
	</div>
	
	<script type="text/javascript">
	/* <![CDATA[ */
		//Die Liste
		var list = document.getElementById('list');
		
		//Alle Elemente in der Liste
		var items = list.getElementsByTagName('li');
		
		//Das aktuell aktive Element (mit der anderen Hintergrundfarbe)
		var active = null;
		
		//Alle Elemente durchlaufen
		for(var i=0; i<items.length; i++) {
			
			//onClick Funktion für jedes Element festlegen
			items[i].onclick = function() {
			
				//Farbe des vorher geklickten zurücksetzen
				if(active != null) {
					active.style.backgroundColor = 'red';
				}
				
				//Farbe des geklickten ändern
				this.style.backgroundColor = 'green';
				
				//Das gerade geklickte Element ist jetzt das aktive
				active = this;
			};
		}
	/* ]]> */
	</script>
</body>

</html>
```


----------



## lahau (25. April 2011)

Hi DANKE!

Nein übernehmen einfach so werde ich es nicht.
Ich werde mich dann jetzt mal damit auseinander setzen und auf mein html script anwenden.
Ich benutze auch schon JS und werde deinen script direkt versuchen auszulagern.

Noch mal danke, ich melde michd ann wieder wenn ich es gescvhaft habe oder halt nicht


----------



## lahau (25. April 2011)

Also....

Habe jetzt ca. 3 Stunden mich damit beschäftigt, verstanden und muste es noch auf meinen CSS und HTML Script anpassen war garnicht mal so leicht =/
Also Top Danke und klapt alles.

Eine frage hätte ich aber noch.
Deinen Script auslagern in eine .js datei.

Im HTML Projekt:

```
<script language="JavaScript" type="text/javascript" src="Javascript.js"></script>
```

die Datei Javascript ist natürlich vorhanden und klapt auch denn dan stehen schon andere funktionen drin.

Ich muss doch jetzt eigentlich nur genau das:

```
var list = document.getElementById('main_menu_ul');     //Die Liste
var items = list.getElementsByTagName('li');            //Alle Elemente in der Liste
var active = null;                                      //Das aktuell aktive Element (mit der anderen Hintergrundfarbe)

for (var i = 0; i < items.length; i++)                  //Alle Elemente durchlaufen
{
    items[i].onclick = function ()                      //onClick Funktion für jedes Element festlegen   
    {
        if (active != null)                             //Farbe des vorher geklickten zurücksetzen
        {
            active.style.backgroundColor = 'aqua';
        }
        this.style.backgroundColor = 'Red';             //Farbe des geklickten ändern
        active = this;                                  //Das gerade geklickte Element ist jetzt das aktive
    };
}
```

in die .js datei reinschareiben und schauen das es die Variabeln und funktionen nicht doppelt gibt oder nicht?

Danke noch mal


----------



## CPoly (25. April 2011)

Ja. Aber du darfst das Skript dann nicht im Kopf der Seite einbinden, denn dann wird es ausgeführt, bevor die Liste überhaupt existiert. Deshalb steht mein Skript auch ganz am Ende der Seite.

Um Namenskonflikte zu verhindern, kannst du den Code auch einfach in eine Anonyme Funktion stecken.


```
(function() {
var list = document.getElementById('main_menu_ul');     //Die Liste
var items = list.getElementsByTagName('li');            //Alle Elemente in der Liste
var active = null;                                      //Das aktuell aktive Element (mit der anderen Hintergrundfarbe)
 
for (var i = 0; i < items.length; i++)                  //Alle Elemente durchlaufen
{
    items[i].onclick = function ()                      //onClick Funktion für jedes Element festlegen   
    {
        if (active != null)                             //Farbe des vorher geklickten zurücksetzen
        {
            active.style.backgroundColor = 'aqua';
        }
        this.style.backgroundColor = 'Red';             //Farbe des geklickten ändern
        active = this;                                  //Das gerade geklickte Element ist jetzt das aktive
    };
}
})();
```

Oder du kannst den Code beim Laden der Seite ausführen. Dann kann es auch im Kopf stehen.


```
//Falls schon jemand eine Funktion festgelegt hat. Die würde sonst überschrieben
var fn = window.onload;

window.onload = function() {
    fn();


    var list = document.getElementById('main_menu_ul');     //Die Liste
    var items = list.getElementsByTagName('li');            //Alle Elemente in der Liste
    var active = null;                                      //Das aktuell aktive Element (mit der anderen 
    Hintergrundfarbe)
 

    for (var i = 0; i < items.length; i++)                  //Alle Elemente durchlaufen
    {
        items[i].onclick = function ()                      //onClick Funktion für jedes Element festlegen   
        {
            if (active != null)                             //Farbe des vorher geklickten zurücksetzen
            {
                active.style.backgroundColor = 'aqua';
            }
            this.style.backgroundColor = 'Red';             //Farbe des geklickten ändern
            active = this;                                  //Das gerade geklickte Element ist jetzt das aktive
        };
    }
};
```


----------



## lahau (25. April 2011)

DANKE

ich werde mich heute abend mal damit auseinander setzen^^


----------



## lahau (26. April 2011)

So,
da wäre auch schon meine nächste frage...

Ich habe jetzt zwei Listen in unterschiedlichen Divs:

```
<div>
     <ul id="menu1" class="menu">
          <li><a href="">Menu1.1</a></li>
          <li><a href="">Menu1.2</a></li>
     </ul>
</div>
<div>
      <ul id="menu2" class="menu">
          <li><a href="">Menu2.1</a></li>
          <li><a href="">Menu2.2</a></li>
          <li><a href="">Menu2.3</a></li>
          <li><a href="">Menu2.4</a></li>
     </ul>
</div>
```

Könnte ich jetzt nicht hingehen und das
	
	
	



```
var list = document.getElementById('menu1');
```
durch ein
	
	
	



```
var list = document.getElementsByClassName('menu');
```
ersetzen?

Danke schon mal


----------



## CPoly (26. April 2011)

Nein, weil getElementById liefert genau ein Element (oder null), wohingegen getElementsByClassName ein Array von Elementen zurück gibt. Du müsstest dann entsprechend den Code anpassen und z.B. eine weitere Schleife einbauen, um alle Element "einzusammeln".


----------



## lahau (26. April 2011)

Hey,

könntest du mir da noch einmal aushelfen?
Das wäre super nett von dir!


Das hier ist der Script den ich zur zeit verwende:

```
var list = document.getElementById('main_menu_ul');     //Die Liste
var items = list.getElementsByTagName('li');            //Alle Elemente in der Liste
var active = null;                                      //Das aktuell aktive Element (mit der anderen Hintergrundfarbe)
for (var i = 0; i < items.length; i++)                  //Alle Elemente durchlaufen
{
    items[i].onclick = function ()                      //onClick Funktion für jedes Element festlegen   
    {
        if (active != null)                             //Farbe des vorher geklickten zurücksetzen
        {
            active.style.backgroundColor = 'aqua';
        }
        this.style.backgroundColor = 'Red';             //Farbe des geklickten ändern
        active = this;                                  //Das gerade geklickte Element ist jetzt das aktive
    };
}
```

Wie schon gesagt wäre super nett von dir! 
DANKE !!


----------



## CPoly (26. April 2011)

Ersetze die ersten beiden Zeilen durch das hier.


```
var lists = document.getElementsByClassName('list');//Die ListeEN

var items = [];//Array für alle Elemente

for(var i=0; i<lists.length; i++) {
	//Alle Elemente der aktuellen Liste
	var tmpItems = lists[i].getElementsByTagName('li');

	//Elemente zum Array hinzufügen
	for(var k=0; k<tmpItems.length; k++) {
		items.push(tmpItems[k]);
	}
}
```

Du solltest aber bedenken, dass "getElementsByClassName" nicht jeder Browser kennt. Vielleicht solltest du einfach um alle deine Menüs ein DIV machen, welchem du eine ID gibst, die du dann einfach benutzt. Dann musst du in deinem Code nur die andere ID einsetzen. Der Code funktioniert für beliebig viele LI Elemente in beliebiger Tiefe.


----------



## lahau (26. April 2011)

Hallo,

ein DICKES DICKES DANKESCHÖN!
Klappt super alles geht reibungslos!

Em wegen den Div's mit den id's darf nicht nur ein Element eine ID besitzen weil man ja sonst klassen benutzen soll?


DANKE!


----------



## CPoly (26. April 2011)

Ich meinte damit so was


```
<div id="menu_wrapper">
     <ul id="menu1" class="menu">
          <li><a href="">Menu1.1</a></li>
          <li><a href="">Menu1.2</a></li>
     </ul>
      <ul id="menu2" class="menu">
          <li><a href="">Menu2.1</a></li>
          <li><a href="">Menu2.2</a></li>
          <li><a href="">Menu2.3</a></li>
          <li><a href="">Menu2.4</a></li>
     </ul>
</div>
```

Jetzt könntest du in dem ursprünglichen Code einfach "menu_wrapper" benutzen und er würde alle LI Elemente finden.


----------



## lahau (26. April 2011)

Achso,

ja das geht halt in meine fall nicht weil ich die menus an unterschiedlichen stellen haben...
Du meintest ja das getElementsByClassName nicht jeder browser zuläst z.b. IE9 -.- Firefox klapt es ohne probleme das ist jetzt natürlich Sch.....ade.

Naja man könnte doch auch mit einem UND-Befehl udn noch einer schleife zwei Ul id's in einem Array zusammenpacken?
Das müsste doch gehen oder?

Ich glaube da setze ich mich heute mal dran und bastel deinen script um... wenn ich erste ergebnise habe stell ich diese mal rein und es wäre nett wenn du dann mal drüber schauen könntest, glaube ich werde eh ein paar fehler machen


----------



## CPoly (26. April 2011)

Also eigentlich müsstest du dafür nicht viel ändern. Da wo du im Moment 


```
var lists = document.getElementsByClassName('list');
```

stehen hast, musst du eben anstelle von getElementsByClassName irgendwie anderes die beiden Listen in das Array bekommen. Das kannst du ja mal versuchen (geht auch in einer Zeile!).


----------



## lahau (26. April 2011)

Ok,
jetzt bin ich wieder ahnungslos^^
ich hätte gedacht das man einfach

```
for(var i=0; i<lists.length; i++) {
    //Alle Elemente der aktuellen Liste
    var tmpItems = lists[i].getElementsByTagName('li');
 
    //Elemente zum Array hinzufügen
    for(var k=0; k<tmpItems.length; k++) {
        items.push(tmpItems[k]);
    }
}
```
diesen teil für die zweite id mit rein nimmt.

wenn es auch in einer zeile zu lösen ginge hätte ich jetzt vermutet

```
var lists = document.getElementById('list'&&'list2');
// ODER
var lists = document.getElementById('list','list2');
```
aber beides klapt nicht.

hängt man einfach wie ich es versuchen wollte zwei id's aneinander oder kommt ein anderes get ElementBy irgentwas da hin?
Ein kleiner script von dir wäre noch mal nett.

Danke


----------



## lahau (27. April 2011)

CPoly hat gesagt.:


> ...getElementById liefert genau ein Element (oder null)...".


Sehe gerade damit hätte ich mir meine versuche auch sparen können 

d.h. das getElementByID muss sich ändern ^^

Hilfe wäre nett


----------



## CPoly (27. April 2011)

Ausgehend von dem Funktionierenden Code mit getElementsByClassName, musst du folgende Zeile


```
var lists = document.getElementsByClassName('list');//Die ListeEN
```

nur dadurch ersetzen


```
var lists = [document.getElementById('menu1'), document.getElementById('menu2')];
```

und schon hast du ein Array mit beiden Listen.


----------



## lahau (27. April 2011)

Ok 

Danke meine ideen waren ja schon mal garnicht soo schlecht nur das man nicht einfach mit && oder , die zwei id's aneinander hängt sondern zwei mal document.getElementById schreibt.

jo ich werde es wieder mal testen und eine rückmeldung geben!

Vielen Dank


----------



## lahau (27. April 2011)

Jo,

noch ein letztes mal danke klappt alles reibungslos, und jetzt macht auch IE9 keine faxen meher


SUPER DANKE


----------



## lahau (28. April 2011)

Hallo,

da ist auch schon meine nächste frage....
Ich möchte einfach nur schauen, das wie vielte Array Element angeklickt wurde und dann anhand der Array Position entscheiden welchen style das vorherig angeklicket element wirder haben soll.


```
var active = null; 
var j = 0;                                 // J wird Deklariert und mit 0 Initialisiert
for (var i = 0; i < items.length; i++)      
{ 
    items[i].onclick = function ()  festlegen   
    {
        if (active != null)      
        {
            if(j < 5)                 // Hier wird geschaut wiegroß b j kleiner 5 ist
            {
                active.style.backgroundColor = '#E7E7E7'; //#323CFF
            }
            else
            {
                active.style.backgroundColor = '#323CFF'; //#323CFF
            }
            
            //active.style.color = '#323CFF'; //#323CFF
        }
        this.style.backgroundColor = '#323CFF'   
        this.style.color = 'white' 
        active = this;    
        j = i;                        // Das momantanige i wird auf j gespeichert damit beim nächen mal geprüft werden kann ob es if oder elses ist    
    };
}
```

ich nehmen mal an das ich da ein denk fehler drin haben...
weil diese 3 zeilen script sind ja fast in jeder sprache gleich  
Hilfe wäre nett
Danke


----------



## CPoly (28. April 2011)

Du überschreibst dir bei jedem Durchlauf dein j und am Ende steht der größte Wert drin. Du müsstest die Deklaration von j in die onclick-Funktion stecken, aber dann funktioniert es immer noch nicht, weil die Zuweisung erst beim Klick ausgewertet wird und dann i wieder den maximalen Wert hat.

Die Lösung ist es, den Code in eine anonyme Funktion zu stecken und damit einen neuen Scope für jeden Schleifendurchlauf zu bekommen, in welchem die Variable dann bestand hat.


```
for (var i = 0; i < items.length; i++)
{
        //Anonyme Funktion. Wird sofort ausgeführt und bekommt als Parameter i übergeben. Innerhalb steht es dann als j zur Verfügung.
	(function(j) {
		items[j].onclick = function ()
		{
                    if(j < 5) {
                        //...
                    }
		};
	})(i);
}
```


----------



## lahau (29. April 2011)

Soweit klapt das.
Mit dem j haben ich ja die Array position des angeklickten element gespeichert.
Ich würde gerne noch ein g mit einfügen welches das vorherige angeklickte element in dem Array noch gespeichert hat.

So sieht mein Script zut zeit aus:

```
for (var i = 0; i < items.length; i++){
     (function(j){
          items[j].onclick = function (){
               if (active != null){
                    if(j < 5){
                         active.style.backgroundColor = '#E7E7E7';
                    }
                    else{
                         active.style.backgroundColor = '#323CFF';
                    }
               }
               this.style.backgroundColor = '#323CFF';
               active = this;
          };
     })(i);
}
```

Der Sinn dahinter ist das ich die Menus unterschiedlich formatieren kann sie aber immer noch zusammen also eins haben.

Vielen Dank schon mal


----------



## CPoly (29. April 2011)

g kannst du ja außerhalb der Schleife deklarieren und mit "-1" initialisieren. Und am Ende der onclick Funktion setzt du g auf j.


----------



## lahau (29. April 2011)

Klapt natürlich!


```
if(j < 5){
            this.style.backgroundColor = '#323CFF';
            this.style.color = '#FFFFFF';
        }
        else{
            this.style.backgroundColor = '#5961FF';
            this.style.color = '#FFFFFF';
        }
```

wenn ich nicht nur den Hintergrund sonder auch die Schriftfarbe ändern möchte reicht es dann nicht einfach this.style noch mal zu schreiben?
So klapt es nicht, die Hintergrundsfarbe wird geändert aber nicht die Schrift farbe.

Danke


----------



## CPoly (29. April 2011)

Doch, das sollte gehen. Wie sieht denn der Rest des codes aus? Setzt du vielleicht irgendwo die Farben nochmal um?


----------



## lahau (29. April 2011)

```
<script type="text/javascript">
/* <![CDATA[ */
var lists = [document.getElementById('main_menu'), document.getElementById('impressum_menu')];
var items = [];     //Array für alle Elemente
for(var i=0; i<lists.length; i++) {         //Alle Elemente der aktuellen Liste
    var tmpItems = lists[i].getElementsByTagName('li');
    for(var k=0; k<tmpItems.length; k++) {      //Elemente zum Array hinzufügen
        items.push(tmpItems[k]);
    }
}
var active = null; 
var g = -1;
for (var i = 0; i < items.length; i++) {
    (function(j) {   //Anonyme Funktion. Wird sofort ausgeführt und bekommt als Parameter i übergeben. Innerhalb steht es dann als j zur Verfügung.
        items[j].onclick = function () {
            if (active != null){    //Farbe des vorher geklickten zurücksetzen
                if(g < 5) {
                    active.style.backgroundColor = '#E7E7E7';   
                }
                else{
                    active.style.backgroundColor = '#323CFF';
                }            
            }
            if(j < 5) {
                this.style.backgroundColor = '#323CFF';
                this.style.color = '#FFFFFF';
            }
            else{
                this.style.backgroundColor = '#5961FF';
                this.style.color = '#FFFFFF';
            }    
            active = this;    //Das gerade geklickte Element ist jetzt das aktive
            g = j;  // Farben 5961FF 323CFF
        };
    })(i);
}
/* ]]> */
</script>
```

Das ist jetzt alles was ich mir mit deiner Hilfe zusammen gebastelt habe.
Es klapt auch alles, bis halt auf die Schriftfarbe.


----------



## lahau (29. April 2011)

Ja klar ich doofi!

```
var tmpItems = lists[i].getElementsByTagName('li');
```
In dem li steht ja nichts das steht in dem <a> xD

Trozdem danke


----------



## lahau (30. April 2011)

Es hat sich noch ein größeres mir unerklärbares Problem ergeben.

Meine Scripts.

```
<style type="text/css" title="text/css" media="screen">
#main_menu li a:hover
{
    background: #5961FF;
    color: Black;
}
</style>

<div id="main_menu">
        <ul>
            <li><a  href=">Link1</a></li>
            <li><a  href=">Link2</a></li>
            <li><a  href=">Link3</a></li>
            <li><a  href=">Link4</a></li>
      </ul>                                                                                                                              
</div>
```


```
var lists = [document.getElementById('main_menu'), document.getElementById('impressum_menu')];
    var items = [];     //Array für alle Elemente
    for (var i = 0; i < lists.length; i++) {         //Alle Elemente der aktuellen Liste
        var tmpItems = lists[i].getElementsByTagName('a');
        for (var k = 0; k < tmpItems.length; k++) {      //Elemente zum Array hinzufügen
            items.push(tmpItems[k]);
        }
    }
    var active = null;
    var g = -1;
    for (var i = 0; i < items.length; i++) {
        (function (j) {   //Anonyme Funktion. Wird sofort ausgeführt und bekommt als Parameter i übergeben. Innerhalb steht es dann als j zur Verfügung.
            items[j].onclick = function () {
                if (active != null) {    //Farbe des vorher geklickten zurücksetzen
                    if (g < 5) {
                        active.style.backgroundColor = '#E7E7E7';
                        active.style.color = '#000000';
                    }
                    else {
                        active.style.backgroundColor = '#323CFF';
                        active.style.color = '#000000';
                    }
                }
                if (j < 5) {
                    this.style.backgroundColor = '#323CFF';
                    this.style.color = '#FFFFFF';
                }
                else {
                    this.style.backgroundColor = '#5961FF';
                    this.style.color = '#FFFFFF';
                }
                active = this;    //Das gerade geklickte Element ist jetzt das aktive
                g = j;  // Farben 5961FF 323CFF
            };
        })(i);
    }
```

Problem: 
Normalefarbe der Links #E7E7E7.
Die Links 1,2,3,4 befinden sich an erster stelle des Array d.h. j und g sind immer < 5.

Wenn ich auf Link1 (Link 1,2,3,4 völlig egal) gehe veränder sich die hintergrundfarbe durch css hover in #5961FF. Klick ich Link1 an nimm er die farbe #323CFF an welche in js steht. 
Gehe ich nu über link 2 (link 2,3,4 völlig egal) verändert die Hintergrundfarbe auch via css.
Wird Link2 nun angeklickt, bekommt Link1 die hintergrundfarbe #E7E7E7 via js und Link2 #323CFF.

Bis hier hin ist auch alles richtig. 
ABER wenn ich nun wieder mit der maus auf link1 gehe und dieser durch css a:hover die hintergrundfarbe annehmen müsste welche dort angegeben ist #5961FF verändert sich nichts. Kurtz gesagt wenn ein link einmal angeklcikt wurde verändert die hintergrundfarbe sich nicht mehr wenn man mit der mausein zweites mal drüber geht.

Weißt du weiter? Ich nicht =/

Vielen dank schon mal


----------



## CPoly (30. April 2011)

Hat mit JavaScript überhaupt nichts zu tun, sondern ausschließlich mit CSS. Genau für diesen Zweck gibt es "!important".


```
#main_menu li a:hover
{
    background: #5961FF;
    color: Black !important;
}
```


----------

