Problem nach Auslagern von Inline Event Handlern

shredder01

Mitglied
Hallo,

ich versuche gerade ein älteres Skript nach meinen Vorstellungen hinzubiegen. Was auch soweit ganz gut funktionierte, solange ich die bisher enthaltenen Inline Javascript Sachen drin gelassen habe. Nun habe ich mir aber in den Kopf gesetzt den Code etwas aufzuräumen und alles Javascript auszulagern.
Leider bekomme ich die entsprechenden Funktionen damit nicht mehr zum laufen. Es gibt keine Fehlermeldung, es passiert einfach nichts.
Das war der alte Code der einfach im HTML-Dokument ausgegeben wurde:
Code:
<script language="Javascript">
     var ie = false;
     var nocolor = 'none';
     if (document.all) { ie = true; nocolor = ''; }
     function getObj(id) {
       if (ie) { return document.all[id]; }
       else {   return document.getElementById(id); }
     }

     function changeColor(id, color) {
       var link = getObj(id);
       if (color == '') {
         link.style.background = nocolor;
         link.style.color = nocolor;
         color = nocolor;
       } else {
         link.style.background = color;
         link.style.color = color;
       }
       eval(getObj(id + 'Obj').title);
     }
 
</script>
Dazu gibt es dann folgendes im HTML:
HTML:
<td><input id="__color_defObj" type="text" size="7"  onChange="changeColor(__color_def, this.value);" name="color_def" value="#4B5D67" \></td>
<td id="__color_def"><script language="javascript">changeColor(__color_def, getObj(__color_defObj).value);</script>&nbsp;</td>

Ich habe jetzt die ganzen Inline-Geschichten entfernt und das obige Script wie folgt abgeändert:
Code:
  var nocolor = 'none';

   function getObj(id) {
        return document.getElementById(id);
     }
   function init(){
    for(i=0;i<count;i++){
     var id = colorset[i];
     var colorelement = getObj(id);
     addEvent(colorelement,'change',function changeColor(id) {
       var color = getObj(id + 'Obj').value;
       var link = colorelement;
       if (color == '') {
         link.style.backgroundColor = nocolor;
         link.style.color = nocolor;
         color = nocolor;
       } else {
         link.style.backgroundColor = color;
         link.style.color = color;
       }
       eval(getObj(id + 'Obj').title);
     },false);
    }  
   }

function addEvent(element, evType, func, useCaption)
{
  if (element.addEventListener) {
    element.addEventListener(evType, func, useCaption);
    return true;
  } else if (element.attachEvent) {
    var retVal = element.attachEvent("on"+evType, func);
    return retVal;
  } else {
    return false;
  }
}

window.load = init;

Das Array colorset enthält die IDs der Tags, weil die dynamisch beim Seitenaufbau eingefügt werden. Es wird zusammen mit der Variablen count am Anfang des Dokuments ausgegeben.
Im Prinzip macht die Funktion nicht weiter als einen Hexadezimalwert aus einem Eingabefeld auszulesen und eine daneben liegende Tabellen-Zelle mit dem entsprechenden Farbwert einzufärben. Gewissermaßen um den User zu verdeutlichen, welche Farbe er da gerade eingestellt hat.

Vielleicht hat ja jemand einen Tipp woran es haken könnte.
Danke!
 
Zuletzt bearbeitet:
Moin,

hier mal eine alternative Lösung:
Code:
addEvent(
          window,
          'load',
          function()
          {
            var inputs=document.getElementsByName('colorinput');
            for(var i=0;i<inputs.length;++i)
            {
              addEvent(
                        inputs[i],
                        'keyup',
                        function()
                        { 
                          var _this=(window.event)
                                      ?window.event.srcElement
                                      :this
                          try{
                               _this.parentNode.nextSibling.style.backgroundColor=_this.value;
                             }catch(e){}
                        },
                        false
                      );
            }
          },
          false);

Alles, was sie im HTML benötigt, ist, dass alle <input>'s den selben Namen haben.
Weiterhin dürfen zwischen den beiden betroffenen <td> keine Leerzeichen stehen(ginge allerdings auch mit, wäre aber umständlicher:))
Also folgendes Markup:
Code:
<td><input name="colorinput"/></td><td>&nbsp;&nbsp;</td>
(Wo und wie oft, ist egal).

Die Funktion addEvent() wird bei dieser Variante weiter benötigt, also nicht entfernen.
 
Danke!
Das werde ich mal ausprobieren.
Hat es Vorteile das window load auch übers addEvent einzubinden, statt es so wie bei meiner Variante aufzurufen?
Aber trotzdem noch mal die Nachfrage von mir: Kann mir jemand sagen was bei meiner Lösung falsch läuft? Es geht mir ja nicht nur darum es zum laufen zu bringen, sondern auch es zu verstehen.

P.S.: Gibt's eigentlich 'ne Möglichkeit sowas vernünftig zu debuggen? Firebug bietet zwar schon bei vielen Dingen interessante Infos, aber in diesem Fall komme ich damit irgendwie auch nicht weiter.
 
Zuletzt bearbeitet:
Mal ganz von hinten angefangen:
window.load = init; ....load ist kein Eventhandler, da sollte besser onload stehen

Weiterhin, bspw. onChange="changeColor(__color_def, this.value);"
...ich sehe dort nirgends eine JS-Variable namens __color_def, das erwartet die Funktion jedoch.

Zum Unterschied von addEvent() und einer normalen Eventüberwachung.
addEvent, besser gesagt die darin verwendeten Methoden addEventListener() und attachEvent() erweitern ein Element um einen Eventhandler, normale Eventüberwachung a'la
objekt.onevent
überschreibt bereits vorhandene Eventhandler.
 
Oh je, ja die Geschichte mit dem window.load statt window.onload ist natürlich blamabel :-(. Aber leider ist das noch nicht die Lösung.

Ich gebe zu die color_def Sache ist etwas verwirrend, aber das hat schon seine Richtigkeit. Das hatte ich im ersten Post so in einem Halbsatz erwähnt, das ich über ein Array colorset die dynamisch erzeugten IDs bekanntmache.
Und wie schon gesagt, der alte Code mit den ganzen Inline-Geschichten funktioniert wie er soll.

Ich hab mal zwei nur auf das wesentliche reduzierte Testseiten aufgesetzt. Einmal mit Deiner Lösung http://designxxl24.de/wp-test/test.html (was auch prima funktioniert) und meine Variante mit allen Feldern, die auch im Original vorkommen http://designxxl24.de/wp-test/test2.html.
Da sagt mir Firebug jetzt , nachdem ich window.onload statt window.load eingefügt habe, merkwürdigerweise "element is null". D.h. das was ich addEvent da als Parameter element übergebe ist leer ... warum auch immer. Naja das finde ich hoffentlich noch raus.

Ich hab Deine Lösung auch mal im Gesamtskript (als Bestandteil eines Wordpress-Plugins) ausprobiert, da funktioniert es leider nicht. Also scheint es noch woanders zu haken.
Mal schauen.
 
Zuletzt bearbeitet:
Jo, hab ich. Ich hab's sogar mehrmals gecheckt.
Die Ausgabe der betroffenen Stelle (natürlich gibt's davon mehrere, für jede ID eine)sieht so aus:
HTML:
<tr>
  <td style="width: 25%;">Tabellenfarbe Wochentage</td>
  <td><input id="__color_tabinnerDaysObj" name="colorinput" type="text" size="7" value="#F7Fcf0" /></td>
  <td id="__color_tabinnerDays" style="border-width: 1px 1px 1px 1px; border-spacing: 1px; border-style: solid solid solid solid; width:15px; height:15px; text-decoration: none; vertical-align: middle;">&nbsp;</td>
  <td style="width: 65%">&nbsp;</td>
</tr>
Ich hab auch schon testweise die noch vorhandenen Inlinestyles entfernt (falls das stören sollte), hat aber auch nichts gebracht.
Die Firebug-Konsole zeigt mir sogar an, das Deine Funktion bei jedem Tastenloslassen ausgeführt wird. Nur wird merkwürdigerweise kein Style eingefügt.
 
Hi,

versuch's mal so, wie von Sven in Post #2 darauf hingewiesen:
HTML:
<tr>
  <td style="width: 25%;">Tabellenfarbe Wochentage</td><td><input id="__color_tabinnerDaysObj" name="colorinput" type="text" size="7" value="#F7Fcf0" /></td><td id="__color_tabinnerDays" style="border-width: 1px 1px 1px 1px; border-spacing: 1px; border-style: solid solid solid solid; width:15px; height:15px; text-decoration: none; vertical-align: middle;">&nbsp;</td><td style="width: 65%">&nbsp;</td>
</tr>


mfg Maik
 
Ok, manchmal kommt dann doch die Blindheit durch :-(.
Danke für's nachdrückliche daraufhinweisen.
Wenn ich alles in Zeile schreibe, dann funktioniert Svens Lösung auch im Gesamtskript.
Fein!
Aber kann mir vielleicht trotzdem nochmal jemand erklären, warum meine Variante nicht funktioniert?
Wieso bekomme ich da bei meinem Test (http://designxxl24.de/wp-test/test2.html) ein "element is null"?
Ich seh es einfach nicht.
 

Neue Beiträge

Zurück