sascha321: Function und return

Hallo

Ich habe eine Funktion "keyup" die eine Funktion "ajax_reguest" aufruft. Nun möchte ich das die Funktion "ajax_reguest" das Ergebnis an die Funktion "keyup" zurück gibt, aber irgendwie klappt das nicht. Der PHP Aufruf und die Abfrage der Datenbank funktioniert, wenn ich bei "return this.responseText;" ein alert mache bekomme ich das Ergebnis was ich brauche, ich möchte es aber bei der Funktion "keyup" weiter verarbeiten. Kann mir da jemand helfen?

Hier der Code

$(document).ready(function() {
  $('#search').keyup(function() {
    if($(this).val().length >= 3) {
      var test = ajax_reguest("suche",$('#search').val());
      alert(test);
    }
  });
}); 

function ajax_reguest (such_option, such_wert) {
  var xhr = new XMLHttpRequest();  
  var params = 'searchoption=' + such_option + '&searchvalue=' + such_wert;
 alert("ajax_request = " + params);
  xhr.onreadystatechange = function() {
    if(this.readyState == 4 && this.status == 200) {
      
      return this.responseText;

    }
  };
  xhr.open("POST", "search.php", true);
  xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  xhr.send(params);  
}
  1. Was ich nicht verstehe ist Dein seltsamer Mix aus jQuery ($(document).ready(function()) und Vanilla-Js.

    Wenn Du meinst jQuery benutzen zu müssen, dann nutze es auch durchgehend. Oder aber Du lässt es (jQuery) ganz. Der Mix ist in etwa wie erst die Blätter in einen Stapel Papier sorgfältig der Reihe nach zu sortieren und zu nummerieren um den kompletten Stapel danach sofort komplett zu schreddern.

    wenn ich bei "return this.responseText;" ein alert mache bekomme ich das Ergebnis was ich brauche, ich möchte es aber bei der Funktion "keyup" weiter verarbeiten. Kann mir da jemand helfen?

    Du musst verstehen, dass der XMLHttpRequest() asyncron arbeitet. Das bedeutet, Du kannst das Ergebnis nicht in der aufrufenden Funktion keyup weiter verarbeiten sondern musst die mit der Antwort auszuführende(n) Aktion(en) statt des alert( this.responseText ); notieren:

      xhr.onreadystatechange = function() {
        if( this.readyState == 4 && this.status == 200 ) {
    
          // Hier ALLES notieren, was zu tun ist
          alert( this.responseText );
    
        }
      };
    

    Der Interpreter kehrt schon zu keyup zurück, nachdem der Request in Auftrag gegeben wurde. Also bevor die Antwort überhaupt vorliegt.

    "Vanilla-Js" ist Javascript ohne Benutzung von Funktions- und/oder Objekt-Bibliotheken oder "Frameworks" wie jQuery & Co.

  2. Hallo,

    du solltest dich mit dem Thema „asynchroner Programmablauf“ beschäftigen. Deine Funtion ajax_reguest startet einen Request, wartet aber nicht auf das Ergebnis. Dieses liegt erst im Evenrhandler onreadystatechange vor. Setzt mal ein alert(this.responseText); in den Eventhandler.

    Mehr dazu im Wiki:

    Gruß
    Jürgen

  3. Mhh keine Ahnung was Du mit Vanilla-Js meinst. Kann mir denn nicht jemand sagen was ich tun muss? Wenn ihr ein Auto kauft, müsst ihr ja auch nicht wissen wie jedes einzelne Teil hergestellt wird. Warum muss ich bis ins kleineste Detail wissen wie was funktioniert?? Ich wäre sehr dankbar, wenn mir jemand sagt wie ich die Daten in die keyup Funktion bekomme.

    Hier noch ein link: https://t3n.de/news/vanillajs-580401/

    Danke

    1. Hallo sascha321,

      Mhh keine Ahnung was Du mit Vanilla-Js meinst.

      https://wiki.selfhtml.org/wiki/Vanilla-JS

      Kann mir denn nicht jemand sagen was ich tun muss?

      Eigentlich möchten wir dich viel lieber beim Lernen unterstützen.

      Bis demnächst
      Matthias

      --
      Rosen sind rot.
      1. Ja das verstehe ich, aber ich brauche das weder beruflich noch werde ich davon leben müssen. Und mit 3 kindern hat man nicht unendlich zeit wenn man sich mal eine kleine Webapp schreiben will. Deswegen verstehe ich nicht das ihr nicht mal über euren schatten springt und einem die Lösung anbietet, auch daraus kann man lernen.

        1. Deswegen verstehe ich nicht das ihr nicht mal über euren schatten springt und einem die Lösung anbietet,

          Geht auch gar nicht, weil Du gar nicht alles gezeigt hast.

          Aber NOCHMAL: Das was Du in Deiner Funktion keyup() mit der Antwort anstellen wolltest musst Du entweder hier

            xhr.onreadystatechange = function() {
              if( this.readyState == 4 && this.status == 200 ) {
          
                // Hier ALLES notieren, was zu tun ist. Beispiel
                document.getElementById( 'antwort' ).innerHTML = this.responseText;
          
              }
            };
          

          oder in einer eigenen Funktion (im Beispiel "withResponse()") definieren:

          function ajax_reguest( such_option, such_wert ) {
            var xhr = new XMLHttpRequest();  
            var params = 'searchoption=' + such_option + '&searchvalue=' + such_wert;
           alert("ajax_request = " + params);
            xhr.onreadystatechange = function() {
              if( this.readyState == 4 && this.status == 200 ) {
                
                withResponse( responseText );
          
              }
            };
            xhr.open( "POST", "search.php", true );
            xhr.setRequestHeader( "Content-type", "application/x-www-form-urlencoded" );
            xhr.send( params );  
          }
          
          function withResponse( string ) {
               document.getElementById( 'antwort' ).innerHTML = string;
          }
          
          
          1. Hallo Danke,

            ja jetzt ist klar was Du meinst, bis die Antwort vom Server kommt ist die Funktion "keyup" schon lange fertig und kann natürlich nichts mehr entgegen nehmen. Tut mir leid habe ich vorhin so nicht aus deinen Zeilen heraus lesen können. Mit der Funktion withResponse die Du in der Funktion "ajax_request" aufrufst, übergibst du die Daten an die neue Funktion wo ich dann das mit machen kann was ich möchte :-) .

            Danke, ich hoffe ich habe das so richtig verstanden.

            Schönen Sonntag noch.

            1. Eines noch:

              Je nachdem, was Du mit dem Ergebnis vor hast, kann es sein, dass Du mit dem Gesamtverhalten "nicht ganz glücklich" bist. Asynchrones Verhalten ist oft, aber nicht in JEDEM Fall vorteilhaft.

              Ändere dann:

              xhr.open( "POST", "search.php", true );
              

              zu

              xhr.open( "POST", "search.php", false );
              
              1. Tach!

                Je nachdem, was Du mit dem Ergebnis vor hast, kann es sein, dass Du mit dem Gesamtverhalten "nicht ganz glücklich" bist. Asynchrones Verhalten ist oft, aber nicht in JEDEM Fall vorteilhaft.

                Anderer Vorschlag: Statt den Browser mit synchronen Requests lahmzulegen, lieber auf die Fetch API umstellen. Das hat den Vorteil, dass der Ajax-Aufruf kürzer gehalten werden kann und dass die Antwort am Ort des Aufrufes zur Verfügung steht. Promise-Technik machts möglich. Für alte Browser ist auf der verlinkten Seite auch ein Polyfill verlinkt.

                dedlfix.

                1. Hallo dedlfix

                  Fetch API … Polyfill

                  hast du dir den Polyfill mal angesehen? Über 500 Zeilen Javascript plus fast 300 Zeilen für den Promise-Polyfill. Da warte ich lieber auf das Supportende von Windows 7 (14. 1. 2020) und vergesse dann den IE 7.

                  Gruß
                  Jürgen

                  1. @@JürgenB

                    Fetch API … Polyfill

                    hast du dir den Polyfill mal angesehen? Über 500 Zeilen Javascript plus fast 300 Zeilen für den Promise-Polyfill. Da warte ich lieber auf das Supportende von Windows 7 (14. 1. 2020) und vergesse dann den IE 7.

                    Warum warten? Dann vergiss doch lieber den Polyfill.

                    Die Seite sollte ohne JavaScript funktionieren. JavaScript ist progressive enhancement. Nutzer, deren Browser Promises und das Fetch-API nicht kennt, bekommen dieselbe UX wie Nutzer, bei denen kein JavaScript ausgeführt wird (und das sind mehr als man denkt). So what?

                    LLAP 🖖

                    --
                    „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
                    1. @@Gunnar Bittersmann

                      Nutzer, bei denen kein JavaScript ausgeführt wird (und das sind mehr als man denkt)

                      Und es dürften bald noch mehr werden: Chrome for Android may start disabling JavaScript on 2G connections.

                      LLAP 🖖

                      --
                      „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
                      1. hallo

                        Und es dürften bald noch mehr werden: Chrome for Android may start disabling JavaScript on 2G connections.

                        3rd party content abzuschalten wäre wohl die bessere Strategie.

                        1. Hallo Beat,

                          Und es dürften bald noch mehr werden: Chrome for Android may start disabling JavaScript on 2G connections.

                          3rd party content abzuschalten wäre wohl die bessere Strategie.

                          dann würde z.B. das Google Maps API nicht mehr funktionieren. Ebenso die CDNs, u.A. von Google.

                          Gruß
                          Jürgen

                      2. Hallo Gunnar,

                        Nutzer, bei denen kein JavaScript ausgeführt wird (und das sind mehr als man denkt)

                        Und es dürften bald noch mehr werden: Chrome for Android may start disabling JavaScript on 2G connections.

                        was hat Javascript mit langsamen Netz zu tun? Können die sich bei Google nicht vorstellen, das man auch ohne riesige Bibliotheken auskommen kann? Warum sind 100kb Javascript schlechter als 100kb css?

                        Ich glaube nicht, dass ich Datenvolumen spare, wenn ich auf dieser Seite das Bild nicht berechne, sondern als png übertrage.

                        Gruß
                        Jürgen

                        1. hallo

                          was hat Javascript mit langsamen Netz zu tun? Können die sich bei Google nicht vorstellen, das man auch ohne riesige Bibliotheken auskommen kann? Warum sind 100kb Javascript schlechter als 100kb css?

                          Praktisch wird mit Javascript oft anderer Inhalt nachgeladen. Es gibt also einen Zusammenhang.

                      3. Mahlzeit,

                        Und es dürften bald noch mehr werden: Chrome for Android may start disabling JavaScript on 2G connections.

                        Meine persönliche Meinung: Wenn es überhaupt so kommt, dann nicht lange denn die "wichtigen" Seiten sind dann nicht mehr erreichbar. Damit meine ich Facebook, Twitter, Instagran, Pinterest usw.

                        --
                        42
                        1. @@m.

                          Und es dürften bald noch mehr werden: Chrome for Android may start disabling JavaScript on 2G connections.

                          Meine persönliche Meinung: Wenn es überhaupt so kommt, dann nicht lange denn die "wichtigen" Seiten sind dann nicht mehr erreichbar. Damit meine ich Facebook, Twitter, Instagran, Pinterest usw.

                          Wenn die Seiten dreiundzwölfzig Sekunden zum Laden brauchen, dann sind sie quasi auch nicht erreichbar. Der Nutzer gibt vorher auf.

                          Es gibt keinen Grund, die Grundfunktionalität dieser Seiten (Zeugs anzeigen, Eingaben entgegennehmen) von JavaScript abhängig zu machen. Womit die Grundfunktionalität aus Sicht der Nutzer gemeint ist.

                          Aus Sicht der Betreiber ist die Grundfunktionalität das Ausschnüffeln der Nutzer. Dazu braucht man freilich JavaScript.

                          LLAP 🖖

                          --
                          „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
                          1. Mahlzeit,

                            Wenn die Seiten dreiundzwölfzig Sekunden zum Laden brauchen, dann sind sie quasi auch nicht erreichbar. Der Nutzer gibt vorher auf.

                            Kennst du Leute bei Facebook, bzw. nutzt du es? Erfahrungsgemäss warten die auch 15 Minuten, schieben dabei Panik und glauben, die Welt geht unter … Ne du, die geben nicht auf denn die meisten Nutzer dieser Seiten sind süchtig.

                            --
                            42
        2. hallo

          Ja das verstehe ich, aber ich brauche das weder beruflich noch werde ich davon leben müssen. Und mit 3 kindern hat man nicht unendlich zeit wenn man sich mal eine kleine Webapp schreiben will.

          Meine 3 Kinder erlauben mir nicht, JQuery zu lernen.

          Ich bin mit html, css und javascript schon mehr als übersättigt.

          Deswegen verstehe ich nicht das ihr nicht mal über euren schatten springt und einem die Lösung anbietet, auch daraus kann man lernen.

          Die Sache ist die, dass JQuery immer irrelevanter wird und heute das letzte auf der Lernliste sein sollte.

        3. Hi there,

          Ja das verstehe ich, aber ich brauche das weder beruflich noch werde ich davon leben müssen. Und mit 3 kindern hat man nicht unendlich zeit wenn man sich mal eine kleine Webapp schreiben will.

          Sorry, aber das ist eines der blödesten Argumente für beabsichtigte Ignoranz, das ich eh gelesen habe.

          Der nächste schreibt dann einfach, er wäre gerade zu besoffen, um die Hintergründe zu kapieren und bittet deshalb einfach um die Lösung. (Was ich im übrigen auch besser verstünde, aber sei's drum...)

    2. Mhh keine Ahnung was Du mit Vanilla-Js meinst.

      Hab ich erklärt (Letzter Satz.).

      Kann mir denn nicht jemand sagen was ich tun muss?

      Hab ich doch.

      1. Dein Ziel, die Antwort auf den "XMLHttpRequest" ganz oder teilweise als Return zu übergeben ist nicht erreichbar.
      2. Du musst die mit der Antwort auszuführende(n) Aktion(en) statt des alert( this.responseText ); notieren.

      WAS davon bringt Dich WARUM nicht weiter?

      1. Weil ich nicht verstehe was Du meinst?

        Ich brauche die Daten aber in der keyup funktion

        1. Ich brauche die Daten aber in der keyup funktion

          Erledigt

    3. Hallo,

      ich habe mich hingesetzt, versucht, deinen Code zu verstehen, eine Antwort geschrieben und noch diverse Links rausgesucht. Was soll ich auf diese Antwort

      Mhh keine Ahnung was Du mit Vanilla-Js meinst. Kann mir denn nicht jemand sagen was ich tun muss? Wenn ihr ein Auto kauft, müsst ihr ja auch nicht wissen wie jedes einzelne Teil hergestellt wird. Warum muss ich bis ins kleineste Detail wissen wie was funktioniert?? Ich wäre sehr dankbar, wenn mir jemand sagt wie ich die Daten in die keyup Funktion bekomme.

      noch erwiedern? Ohne Grundwissen kannst du das Programmieren vergessen. Und um dein Zitat aufzugreifen: du willst kein Auto kaufen, du willst eins (um)bauen. Ajax ist mehr, als nur Ralleystreifen Aufkleben.

      Gruß
      Jürgen

    4. Mahlzeit,

      Mhh keine Ahnung was Du mit Vanilla-Js meinst. Kann mir denn nicht jemand sagen was ich tun muss?

      Diese beiden Sätze lesen sich für mich so: "Ich hab keinen Bock, was zu lernen, wer macht es mir umsonst und kostenlos und lässt sich dann noch anpflaumen weil es so lange gedauert hat".

      --
      42
  4. Hallo sascha321,

    falls Du nach dem Ausbruch der Flamewars noch mitliest…

    jQuery beginnt tatsächlich, obsolet zu werden. Vieles, was früher ohne jQuery ein Krampf war, wird heute von den Browsern unterstützt, vor allem EINHEITLICH unterstützt.

    Aber wenn Du an jQuery gewöhnt bist, spricht sicher nichts dagegen, es weiter zu benutzen. Verwendest Du die aktuelle Version (jquery-3.3.1.min.js)?

    Problem ist nur: Auch jQuery entwickelt sich weiter. Zum Beispiel ist das Registrieren eines Ready-Handlers auf diverse Weisen möglich, aber nur eine davon gilt bei jQuery nicht als missbilligt, nämlich diese:

    $(function() {
       // dinge die bei ready zu tun sind
    });
    

    Das ist auch die kompakteste Variante; es ist also ganz nett, sich daran zu gewöhnen.

    Zweitens: Du solltest NICHT das keyup Event verwenden, um Textänderungen eines Eingabefeldes mitzubekommen. Hier gibt es bessere Events. Nachteil 1 von Keyup: Es feuert auch bei Shift-Tasten oder den Pfeilen. Nachteil 2 von Keyup: Es feuert NICHT, wenn Du Text in das Suchfeld per Cut+Paste einfügst. Ob es auf einem Gerät mit Bildschirm-Tastatur feuert, ist unsicher. Mit Windows-Bildschirmtastatur kommt es, ob es auf Android ähnlich ist, weiß man nicht. Besser ist das input-Event, das feuert bei jeder Änderung eines Textfeldes.

    Drittens: Wenn Du schon jQuery verwendest, dann nutze es auch für AJAX. Es gibt da ein paar praktische Helper.

    Viertens: JavaScript ist eine Sprache, mit der man wunderbar funktional programmieren kann. jQuery verwendet an vielen Stellen Callback-Funktionen, um für asynchrone Aktivitäten die Fortsetzung bereitstellen zu können. Das kannst Du auch selbst nutzen.

    Fünftens: Funktionen benennt man nach Möglichkeit sprechend. Eine Funktion „ajax_reguest“ zu nennen, ist nicht gut, weil der Name nicht sagt, was die Funktion inhaltlich tut (vom Schreibfehler reguest statt request mal abgesehen; offenbar hast Du dich da mal verhört).

    $("#search").on("input", function(evt) {
       if (this.value.length > 3) {
          sucheBegriff(this.value, function(ergebnis) {
             // Dinge, die mit dem Ergebnis zu erledigen sind
             alert(ergebnis);
          });
       }
    });
    
    function sucheBegriff(suchBegriff, ergebnisBehandler) {
       $.post(
          "search.php", 
          { searchoption: "suche", searchvalue: suchBegriff },
          ergebnisBehandler,
          "text");
    }
    

    Das Auslesen des Textes im Suchfeld kann man mit this.value machen, dazu braucht es weder $(this).val() noch $("#search").val().

    Die jQuery.post-Funktion hat den Vorteil, dass sie sich um die Codierung der Parameter selbst kümmert. Dein Code tut das nicht, ein Zeichen mit Sonderbedeutung im Suchfeld (z.B. &, =, # oder sogar ein Leerzeichen) würde den Aufruf durcheinanderbringen. Wenn Du die Daten als Objekt angibst, verpackt jQuery sie für dich als FormData.

    Den Ergebnisbehandler kannst Du dann direkt an jQuery durchreichen. Wenn die Daten da sind, wird er von jQuery aufgerufen. Wenn Du vom Server nicht nur Text zurückgibst, sondern eine Datenstruktur, solltest Du Dich mit den alternativen dataType-Angaben im vierten Parameter befassen, die jQuery unterstützt.

    Hier geht's zur Dokumentation

    Man könnte auch die jQuery-Promises verwenden und die Sache noch etwas eleganter machen, aber ich will jetzt nicht zu viel auf einmal bringen.

    Rolf

    --
    sumpsi - posui - clusi
    1. @@Rolf B

      Aber wenn Du an jQuery gewöhnt bist, spricht sicher nichts dagegen, es weiter zu benutzen.

      Doch, dagegen spricht:

      • 87 Kilobyte, die erstmal übertragen werden müssen.

      • zusätzliches JavaScript, dass ausgeführt wird

      LLAP 🖖

      --
      „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann