RobRobson: Unterfunktion/ Mitführen eines Arrays

Hallo,

sollte eigentlich ganz einfach sein, aber ich bekomms nicht gebacken.

Ein Array will ich gern über die onClick Funktion eines Buttons an eine Unterfuntion weitergeben zur Verarbeitung. Der Standardweg klappte nicht:

  
function protokoll(){  
    $.post('prt.php',function(protokollarray){  
       $('div').html('<submit onclick="get(protokollarray)">hole Daten</submit>');  
       //alternative  
       $('div').html('<submit onclick="get('+protokollarray+')">hole Daten</submit>');  
       ...  
       },'json');  
  
     function get(r) {  
        alert(r.erstes);  
        }  
}  

Also hab ich es mit einem global definierten Array versucht:

  
var protokollarray = new Array();  
function protokoll(){  
    $.post('prt.php',function(){  
       $('div').html('<submit onclick="get(protokollarray)">hole Daten</submit>');  
       ...  
       });  
  
     function get() {  
        alert(protokollarray.erstes);  
        }  
}  

klappte leider auch nicht.
Ich kann auch keine Informationen für die Lösung finden.
Kann mir da wer auf die Sprünge helfen?

Danke und Viele Grüße,
Rob

PS: ob "get()" eine SubFunktion ist, oder nicht ist mir egal. Es funktioniert in beiden Fällen nicht.

  1. Ein Array will ich gern über die onClick Funktion eines Buttons an eine Unterfuntion weitergeben zur Verarbeitung. Der Standardweg klappte nicht:

    Der Standardweg mit JS sollte ein anderer sein. In dem du ein Element nicht mit HTML sondern mit createElement erzeugst und diesem dann den jeweiligen Eventhandler. Dann ist deine Fragestellung auch kein Problem mehr. jquery bietet für sowas eine Reihe von Funktionen, ich kenn mich damit nicht so aus, aber es gibt ja eine relativ gute Dokumentation.

    klappte leider auch nicht.
    Ich kann auch keine Informationen für die Lösung finden.

    Auch nicht in der Fehlerkonsole?

    Struppi.

    1. Hallo und Danke schonmal,

      Der Standardweg mit JS sollte ein anderer sein. In dem du ein Element nicht mit HTML sondern mit createElement erzeugst und diesem dann den jeweiligen Eventhandler. Dann ist deine Fragestellung auch kein Problem mehr.

      Ich denke das die JQery Funktion .html() genau das tut (createElement). Dafür ist dieses Framework IMO da.
      Aber ich werds mir gleich nochmal genauer anschauen.

      jquery bietet für sowas eine Reihe von Funktionen, ich kenn mich damit nicht so aus, aber es gibt ja eine »» relativ gute Dokumentation.

      Ich glaube nicht das es ein jquery Frage ist. Sondern eine wie man Array in Javascript verwenden kann.
      Total verrückt macht mich ja das Beispiel 2 (mit dem globalen Array) nicht funktioniert.

      klappte leider auch nicht.
      Ich kann auch keine Informationen für die Lösung finden.

      Auch nicht in der Fehlerkonsole?

      Nein, die ist komplett leer.

      Nachtrag:
      Beispiel 2 Funktioniert. Wenn man akzeptiert das der Arrayinhalt trotz globalem Charakter der Variale nur wärend der CALLBACK Funktion existiert. Danach nicht mehr.
      Also muss man sich eine ArrayKopie ziehen! Die Kopie als globale Variable zu definieren reicht dann auch völlig aus. Diese ist dann in der get() Funktion nutzbar.

      Also Du hattest wohl recht, es ist ein JQuery "Problem". (Als PHP oder JS schreiber vergisst man sehr schnell die definiert kurze Lebensdauer von variablen im C Umfeld :-D)

      Viele Grüße,
      Rob

      1. Ich denke das die JQery Funktion .html() genau das tut (createElement).

        .html('...') macht (neben viel Auräumarbeit) intern .innerHTML = '...'. Damit sollte man i.d.R. keine Event-Handler registrieren. Es funktional auf die klassische Art zu tun ist viel flexibler.

        Was Struppi meint geht in jQuery z.B. so, wie ich es gezeigt habe: $('<button>Foo</button>').click(clickHandler) erzeugt ein button-Element und registriert einen Event-Handler. Dieser Ausdruck gibt das jQuery-Objekt mit dem Element zurück, man muss es dann noch mit append/appendTo o.ä. einhängen.

        Mathias

  2. function protokoll(){
        $.post('prt.php',function(protokollarray){
           $('div').html('<submit onclick="get(protokollarray)">hole Daten</submit>');

    Es gibt kein submit-Element. Suchst du vielleicht <button>?

    Natürlich kannst du hier im Event-Handler nicht auf protokollarray zugreifen. protokollarray ist eine lokale Variable der Callback-Funktion, der Event-Handler-Code wird aber im globalen Kontext ausgeführt. Da ist die Variable in dem Fall nicht verfügbar.

    //alternative
           $('div').html('<submit onclick="get('+protokollarray+')">hole Daten</submit>');

    Das funktioniert, wenn sich nur einfache Werte im Array befinden und er sich somit ohne Verluste in einen String umwandeln lässt. Da du hier aber auf eine Eigenschaft »erstes« zugreifst, handelt es sich wahrscheinlich eher um ein Object, keinen klassischen Array:

    function get(r) {
            alert(r.erstes);
            }

    Also hab ich es mit einem global definierten Array versucht:

    Es ist die schlechteste Lösung, einfach alle Variablen global zu machen.

    var protokollarray = new Array();
    function protokoll(){
        $.post('prt.php',function(){
           $('div').html('<submit onclick="get(protokollarray)">hole Daten</submit>');
           ...
           });

    function get() {
            alert(protokollarray.erstes);
            }
    }

    
    >   
    > klappte leider auch nicht.  
      
    Natürlich funktioniert das nicht. An keiner Stelle wird der globalen Variable ein Wet zugewiesen. Die Ajax-Callback-Funktion nimmt die Serverantwort gar nicht mehr als Parameter entgegen. Du müsstest schon schreiben:  
      
    $.post('...', function (response) {  
      protokollarray = response; // speichere Antwort global  
      $('div').html('<button onclick="get()">hole</button>'):  
    });  
      
    Eine Übergabe von protokollarray an get ist in dem Fall unnötig, es ist schließlich eine globale Variable.  
      
    Und dann in get:  
      
    function get() {  
      alert(protokollarray.erstes);  
    }  
      
    Eine saubere Lösung sähe aber anders aus. Es ergibt hier durchaus Sinn, mit verschachtelten Funktionen zu arbeiten, die gegenseitig auf ihre Variablen zugreifen können ([Closures](http://molily.de/js/organisation-verfuegbarkeit.html#closures)).  
      
    ~~~javascript
    function protokoll () {  
       // Funktionsvariable, auf die verschachtelte Funktionen zugreifen können  
       var response;  
      
       $.post('prt.php', callback, 'json');  
      
       function callback (r) {  
          // Weise Variable einen Wert zu  
          response = r;  
          // Element mit DOM erzeugen und Event-Handler registrieren  
          var button = $('<button>hole Daten</button>').click(getData);  
          // Button einhängen  
          $('div').empty().append(button);  
       }  
      
       function getData () {  
          alert(response.erstes);  
       }  
    }
    

    Mathias

    1. var button = $('<button>hole Daten</button>').click(getData);
            // Button einhängen
            $('div').empty().append(button);

      Dafür gibt es .replaceWith() - da ist auf einen Blick ersichtlich, was gemeint ist. Zwar muss der Selektor davor leicht anders aussehen, aber das dürfte kein Thema sein.

      1. $('div').empty().append(button);

        Dafür gibt es .replaceWith() - da ist auf einen Blick ersichtlich, was gemeint ist.

        replaceWith() wechselt ein Element durch ein anderes. Das ist hier nicht gemeint.

        Zwar muss der Selektor davor leicht anders aussehen, aber das dürfte kein Thema sein.

        Wie sähe das denn aus? 'div > :first'? Da käme ich um das Löschen der restlichen, folgenden nicht herum. Das wäre letztlich nicht einfacher als empty().append().

        Gibts nicht sowas wie html() nur für DOM-Elemente?

        Mathias

        1. replaceWith() wechselt ein Element durch ein anderes. Das ist hier nicht gemeint.

          Ich hab' das wohl falsch verstanden, ich ging davon aus dass in dem div-Element ohnehin nur ein Button zu finden ist, der einerseits das einzige Kind dieses div-Elements ist und andererseits einfach durch einen anderen ersetzt werden soll.

          Zwar muss der Selektor davor leicht anders aussehen, aber das dürfte kein Thema sein.

          Wie sähe das denn aus? 'div > :first'? Da käme ich um das Löschen der restlichen, folgenden nicht herum. Das wäre letztlich nicht einfacher als empty().append().

          Siehe oben $('div>button').replaceWith(neuer_button);

          Gibts nicht sowas wie html() nur für DOM-Elemente?

          Wenn du tatsächlich alles wegschmeissen (unabhängig der Anzahl der Elemente) und durch etwas anderes (eine ggf. andere Anzahl an Elementen) ist empty().append() sicher das vernünftigste ja. Das tut dann ansich das was .html() tut, nur mit DOM-Elementen.

    2. Hi,
      ich will das Thema nur nochmal kurz aufwärmen um eine Inzu zu komplettieren.

      function protokoll(){
          $.post('prt.php',function(protokollarray){
             $('div').html('<submit onclick="get(protokollarray)">hole Daten</submit>');

      Es gibt kein submit-Element. Suchst du vielleicht <button>?

      Das mit dem <submit> funktioniert schon. Wird im Button Tutorial von JQuery auch so gezeigt.
      Allerding muss ich dringend davon abraten diesen Weg zu gehen!
      Denn eben im IE8 ist aufgefallen das dieses Konstukt beim Versuch es mit JQuery anzusprechen mittels $("submit") zum kompletten Ausfall der Seite im IE8 führt auf der so ein Element enthalten ist. Also doch besser FINGER WEG davon!

      Viele Grüße,
      Rob

      1. Das mit dem <submit> funktioniert schon. Wird im Button Tutorial von JQuery auch so gezeigt.

        Dann ist das Tutorial falsch oder du hast du etwas falsch abgeschrieben.

        Allerding muss ich dringend davon abraten diesen Weg zu gehen!
        Denn eben im IE8 ist aufgefallen das dieses Konstukt beim Versuch es mit JQuery anzusprechen mittels $("submit") zum kompletten Ausfall der Seite im IE8 führt auf der so ein Element enthalten ist. Also doch besser FINGER WEG davon!

        Das liegt daran, was ich bereits sagte: Es gibt kein submit-Element, allerdings ein http://de.selfhtml.org/html/formulare/klickbuttons.htm@title=button-Element.

        Du kannst natürlich <husseldiguggeldidu> schreiben und manche Browser werden dieses unbekannte Element trotzdem verarbeiten und ins DOM einfügen. Es hat dann aber keine Bedeutung und du kannst nicht davon ausgehen, dass du ihm Attribute wie onclick verpassen kannst und alles wie gewünscht funktioniert. Auch das Ansprechen über das DOM muss nicht zwangsläufig funktionieren. Insbesondere der IE < 9 ignoriert solche unbekannten Tags. Daher sollte man nicht einfach irgendwelche eigenen HTML-Elemente »erfinden«, sondern die <http://de.selfhtml.org/html/referenz/elemente.htm@title=definierten Elemente> verwenden.

        Mathias