salat: Event übergeben

Hallo,
ich möchte in js das Event von einem Element an ein anderes übergeben und erweitern.

So siehts aus:

  
<input type="text" name="text1" onblur="mach_1()"/>  
<input type="text" name="text2" onblur="mach_2()"/>  

Mit javascript will ich nun, dass bei "onblur" von text2 zuerst mach_2() und dann mach_1() ausgeführt wird.

habe das bisher so geregelt:

  
document.getElementsByName('text2').onblur = document.getElementsByName('text2').onblur + ";" + document.getElementsByName('text1').onblur  

Leider funktioniert das mit dem zusammenhängen nicht.

  
document.getElementsByName('text2').onblur = document.getElementsByName('text1').onblur  

das funktioniert jedoch.

Was muss ich ändern?

  1. @@salat:

    nuqneH

    So siehts aus:

    <input type="text" name="text1" onblur="mach_1()"/>

    <input type="text" name="text2" onblur="mach_2()"/>

    
    >   
    > Mit javascript will ich nun, dass bei "onblur" von text2 zuerst mach\_2() und dann mach\_1() ausgeführt wird.  
      
    Warum schreibst du daas nicht so in @onblur rein?  
      
    Qapla'
    
    -- 
    Gut sein ist edel. Andere lehren, gut zu sein, ist noch edler. Und einfacher.  
    (Mark Twain)
    
  2. Lieber salat,

    document.getElementsByName('text2').onblur = document.getElementsByName('text1').onblur
    das funktioniert jedoch.

    das wundert mich sehr, denn getElement_s_ByName gibt eine NodeList zurück, die wie ein Array zu behandeln ist. Ich hätte jetzt zumindest document.getElementsByName('text2')[0].onblur erwartet.

    Du kannst das on_irgendwas-Event eines beliebigen Elements dadurch auslösen, indem Du meinElement.on_irgendwas() notierst. Zum Bleistift so:

    document.getElementsByName('text2').onblur = function () {  
        mach1();  
        document.getElementsbyName('text1').onblur();  
    }
    

    Liebe Grüße,

    Felix Riesterer.

    --
    ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
    1. document.getElementsByName('text2').onblur = document.getElementsByName('text1').onblur
      das funktioniert jedoch.

      das wundert mich sehr, denn getElement_s_ByName gibt eine NodeList zurück, die wie ein Array zu behandeln ist.

      Es »funktioniert« wahrscheinlich in dem Sinne, dass es keinen Fehler ausspuckt.
      Bei der NodeList wird eine neue Eigenschaft angelegt. Diese bekommt den Wert einer nicht vorhandenen Eigenschaft einer anderen NodeList - also undefined.
      Das geht, weil man jedem Objekt in ECMAScript 3 neue Eigenschaften zuweisen kann, aber eine weitergehende Wirkung hat das nicht.

      Du kannst das on_irgendwas-Event eines beliebigen Elements dadurch auslösen, indem Du meinElement.on_irgendwas() notierst. Zum Bleistift so:

      document.getElementsByName('text2').onblur = function () {

      mach1();
          document.getElementsbyName('text1').onblur();
      }

        
      Von der Codeorganisation halte ich es für sinnvoller, den text1-blur-Handler als separate Funktion zu notieren und dann diese über ihren Namen aufzurufen (ggf. mit Übergabe des Event-Objekts und Korrektur von this).  
        
      Mathias
      
  3. Moin!

    ich möchte in js das Event von einem Element an ein anderes übergeben und erweitern.

    So siehts aus:

    <input type="text" name="text1" onblur="mach_1()"/>
    <input type="text" name="text2" onblur="mach_2()"/>

    
    >   
    >   
    > Mit javascript will ich nun, dass bei "onblur" von text2 zuerst mach\_2() und dann mach\_1() ausgeführt wird.  
      
    aeh... Wenn mach1() ausgefuehrt werden soll und nicht "was bei text1 ausgefuehrt wird" dann doch einfach  
      
    ~~~javascript
      
    document.getElementsByName('text2')[0].onblur = function()  
    {  
     mach_2();  
     mach_1();  
    }  
    
    

    Oder, auf deine Art notiert:
    <input type="text" name="text2" onblur="mach_2(); mach_1()"/>
    Davon wuerde ich aber absehen. JS hat im HTML nicht viel verloren.

    Falls das ganze dynamisch sein soll also mach_2() und "das was bei text1 gemacht wird, was immer das ist" musst Du natuerlich feststellen, was bei text1 so gemacht wird.

    Das hier hab ich mal gebastelt. Kannst ja mal mit rumspielen:

      
    // injects code into function code  
    // returns new code with injection  
    // nc new code, eh eventhandler/function (old code)  
    function injectCode(nc, eh)  
    {  
      
     // check if eventhandler or function exists  
     //alert(typeof eh);  
     if (!eh)  
     {  
      eh = function(){}  
     }  
      
      
     //alert("new code: " + nc);  
     //alert("function code: " + eh);  
      
     // get code out of eventhandler or function  
      
     // read function in eventhandler  
     var fc = eh.toString();  
      
     // get code out of function  
     var fBeg = fc.indexOf("{")+1;  
     var fEnd = fc.lastIndexOf("}");  
     var actCode = fc.slice(fBeg, fEnd);  
      
     //alert("actual code: " + actCode);  
      
     // add new code after old code  
     actCode = actCode + nc;  
      
     //alert("modified code: " + actCode);  
      
     return actCode;  
    }  
    
    

    Beispiel einer Integration:

      
    var myElement=document.getElementsByName('text2')[0];  
    myElement.onblur = function()  
    {  
     alert('blur');  
    }  
    myElement.onblur = new Function(injectCode("alert('neuer code');", myElement.onblur));
    
    --
    Vergesst Chuck Norris.
    Sponge Bob kann unter Wasser grillen!
    1. Falls das ganze dynamisch sein soll also mach_2() und "das was bei text1 gemacht wird, was immer das ist" musst Du natuerlich feststellen, was bei text1 so gemacht wird.

      Das hier hab ich mal gebastelt. Kannst ja mal mit rumspielen:

      Das ist mit Verlaub der schlechteste Weg. In JavaScript ist es so gut wie nie nötig, Code als String zu notieren. Und weder ratsam noch nötig, Funktionskörper in Strings umzuwandeln. Manche Engines können das gar nicht, der Standard erfordert es nicht. Techniken wie eval() und new Function() sind aus verschiedenen Gründen zu vermeiden - und sie können auch so gut wie immer durch eine performantere Lösung ersetzt werden.

      JavaScript ist eine funktionale Sprache, und wenn man eine Funktion erweitern will, dann erzeugt man eine neue Funktion, die die alte aufruft und davor oder danach noch weiteres tut. Einfach gehalten:

      function callAfter(first, second) {  
        return function () {  
          first.apply(this, arguments);  
          second.apply(this, arguments);  
        }  
      }  
      element.onblur = callAfter(element.onblur, function () {  
         alert('ergänzung');  
      });
      

      Der Schlüssel hierzu sind Closures.
      http://molily.de/js/organisation-verfuegbarkeit.html#closures
      http://molily.de/javascript-core/#closures
      Dasselbe Schema wird im Falle von Binding und Currying bzw. Partial Function Application angewendet.

      Mathias

      1. Moin!

        Hm. Vielleicht hab ich das nicht gut genug getrennt. Das war keine Lösung, sondern eine Aufforderung mit dem Code zu spielen. Wenn man die auskommentierten Zeilen aktiviert, kann man nett sehen wie das mit den Funktionen so läuft. Damit wird einem auch klar, warum myElement.onclick = myElement.onclick + ";" + myOtherElement.onclick nicht funktioniert.

        Mir hat diese lustige kleine Funktion jedenfalls sehr geholfen, als ich mal vor dem Problem stand Funktionen erweitern zu wollen. Einfach was zu machen, was irgendwo steht, hilft einem nicht zu verstehen, was man da eigentlich macht. Deshalb hab ich den kleinen Puffel auch noch auf der Platte.

        --
        Vergesst Chuck Norris.
        Sponge Bob kann unter Wasser grillen!
  4. Hallo,

    Mit javascript will ich nun, dass bei "onblur" von text2 zuerst mach_2() und dann mach_1() ausgeführt wird.

    habe das bisher so geregelt:

    Und du musst es dynamisch mit JavaScript ändern?
    Jegliches Event-Handling sollte man zumindest mit angemessenen Helferfunktionen vornehmen, üblicherweise addEvent() und removeEvent() genannt. Damit kannst du bei text2 einfach eine weitere Handler-Funktion registrieren und sie bei Bedarf wieder abmelden.

    document.getElementsByName('text2').onblur = document.getElementsByName('text2').onblur + ";" + document.getElementsByName('text1').onblur

      
    Das wird - abgesehen von der falschen Verwendung von getElementsByName - so nicht funktionieren, da onblur entweder null oder ein Funktionsobjekt enthält. Wird ein Funktionsobjekt in einen String umgewandelt, kommt i.d.R. etwas wie function(...){...} heraus. Dann würdest du einen String zusammenbauen, der z.B. »function(){ alert('eins') };function(){ alert('zwei) }« lautet. Erstens wäre das ein Syntaxfehler (der Browser nimmt bei function... eine Funktionsdeklaration an), zweitens würden diese Funktionen nur notiert, nicht ausgeführt, und drittens muss man onblur auch wieder [ein Funktionsobjekt zuweisen](http://molily.de/js/event-handling-grundlagen.html#fehler-code-als-string).  
      
    Wie gesagt sollte man das funktional lösen, anstatt mit Strings zu hantieren.  
      
    Mathias