A. Henkelmann: Event-Handler zentral registrieren u. Funktionen übernehmen

Beitrag lesen

Huhu!

YES! Jippie, es funktioniert! Danke, danke, danke, der Tipp mit .call() war genau richtig!

Wieso funktioniert:
this.id = 'gnn'; alert(this.id);
aber das hier nicht:
alertTest('Diese ID: ' + this.id);
???

Wenn du den Aufruf wirklich im onclick-Attribut im HTML notiert hast - dann wir die Funktion im Kontext des Elements ausgeführt.

Sowas hatte ich mir schon gedacht, dass halt "this" beim Aufruf nicht genau referenziert ist. Mich wunderte nur, dass es im ersten Fall klappt und im zweiten nicht. Für mich sieht beides nämlich fast gleich aus... ja, gut, das eine ist ein Funktionsaufruf, das andere nicht, aber bei beiden geht es um "this". Da muss ich wohl noch viiiel lernen...

Dieser Kontext geht dir aber verloren, wenn du hier

// Hat dieses Element bereits eine onclick-Funktion?
    // dann schreibe sie in das Array:
    if(objHandlerElement[i].onclick){
       arrOnClickEvents[i] = objHandlerElement[i].onclick;

die Funktionen alle in dein Array legst.

Ja, aber nur im zweiten Fall, im ersten nicht. Das hat mich doch sehr verwundert.

// Das lang-Attribut zu setzen ist ein Workaround, damit der Link weiss,
    // welcher Array-Index der richtige ist:
    objHandlerElement[i].lang = i;

Pfui bah. Warum dazu das lang-Attribut missbrauchen?

Ja, ich weiß und du hast vollkommen recht. *schäm* Aber ich wollte erstmal das eine Problem lösen, bevor ich mir Gedanken mache, wie ich denn ein eigenes Attribut erfinde.

Du kannst auch problemlos eigene Eigenschaften an Javascript-Objekte anhängen, bspw. objHandlerElement[i].arrOnClickEventsIndex = i;

Danke! Das habe ich dann auch so gemacht.

[...]

call bzw. apply könnten dir hier helfen, die Funktion auch wirklich im Kontext des ursprünglichen Elementes/Objektes auszuführen.

Ja, ja, ja, das war es!
Hier nochmal der funktionierende Code:

var arrOnClickEvents = new Array();

window.onload = setOnclickHref;

function setOnclickHref(){
   var strTagname = "a";
   var strTarget = "_top";
   var objHandlerElement = document.getElementsByTagName(strTagname);
   if(!objHandlerElement){
      return false;
   }
   // durch alle betroffenen Elemente iterieren:
   for(var i=0; i<objHandlerElement.length; i++)
   {
      if(objHandlerElement[i].target == strTarget){
         // Hat dieses Element bereits eine onclick-Funktion?
         // dann schreibe sie in das Array:
         if(objHandlerElement[i].onclick){
            arrOnClickEvents[i] = objHandlerElement[i].onclick;
         }
         // Neues Attribut setzen, damit der Link weiss, welcher Array-Index der richtige ist:
         objHandlerElement[i].intIndexForArrOnClickEvents = i;
         // Hier wird nun eine neue Funktion an das onClick-Event gebunden:
         objHandlerElement[i].onclick = function() {
            if(arrOnClickEvents[this.intIndexForArrOnClickEvents])
            {
               // eine bereits vorhanden onclick-Funktion wird aus dem Array geholt und ausgefuehrt:
               arrOnClickEvents[this.intIndexForArrOnClickEvents].call(this);
            }
            alert(this.target + " " + this.intIndexForArrOnClickEvents);
         } // Ende neue Funktion
      } // Ende if target=strTarget
   } // Ende for
}

Also, ob das nun so schlau ist wie ich das hier mache, das sei mal dahingestellt. Immerhin verstehe ich zumindest was ich da mache. :) Anders bei dem Code aus der Quelle:

Btw: Diverse Ansätze für sowas sind bereits entwickelt worden, bspw. http://ejohn.org/projects/flexible-javascript-events/

Da weiß ich leider nur ungefähr, was da passiert und gar nicht, wie ich das wo genau in meiner Funktion einbaue. Und da ich schon über ne Woche experimentiere, wollte ich schnelle Ergebnisse. Und jetzt klappt's! *poing poing poing* Meine Woche ist gerettet!

Vielen, vielen Dank nochmal!

... jetzt muss ich's nur noch im Safari testen...

Liebe Grüße
Anja  ;->