Klaus: Jquery Frage

Hi,

bei Aufruf einer Seite führe ich folgenden JS-Code aus, wenn $_GET['reiter'] den Wert 2 hat.

Nun habe ich die (native) Funktion "reiter" entfernt, weil ich das Wechseln der Reiter im restlichen Script über ein Jquery onclick Event ausführe. Zuvor war es auch über ein (natives) Onclick-Event, das die Funktion "reiter" aufrief.

  
if ($_GET['reiter'] == 2) {  
echo ("  
<script type=\"text/javascript\">  
reiter('r2','r1');  
</script>  
");  
}  

Geht sowas adäquat auch über Jquery?

Also, wie kann ich den Code

  
$(\"#r1\").toggle(200);  
$(\"#r2\").toggle(400);  
$(\"#t2\").removeClass(\"deaktiv\");  
$(\"#t2\").addClass(\"aktiv\");  
$(\"#t1\").removeClass(\"aktiv\");  
$(\"#t1\").addClass(\"deaktiv\");  
});  
  

ausführen, wenn beim Aufruf der Seite $_GET['reiter'] == 2 ist?

Und muß der css-Klassenwechsel so kompliziert sein, wie ich es notiert habe? Die Klasse toggeln hatte nicht die Wirkung, die ich wollte.

Klaus

  1. Meine Herren!

    Also, wie kann ich den Code [...] ausführen, wenn beim Aufruf der Seite $_GET['reiter'] == 2 ist?

    Du hast vermutlich einen URL der Gestalt: http://example.com/?reiter=2
    In JavaScript gibt es keine globale $_GET-Variable, wie in PHP, die alle URL-Parameter enthält.
    Dafür gibt es in JavaScript das document.location.href-Objekt, dass die gesamten URL beinhaltet unt mit URL. Daraus müsstest du den Parameter reiter=2 selber extrahieren. Dazu gibt es auch schon tausende Helferlein.

    Und muß der css-Klassenwechsel so kompliziert sein, wie ich es notiert habe? Die Klasse toggeln hatte nicht die Wirkung, die ich wollte.

    So kompliziert sieht er doch gar nicht aus. Mal abgesehen von der Wortneuschöpfung "deaktiv" :P
    Mit toggleClass und CSS-Transitions könntest du die paar Zeilen sicher noch weiter kürzen.

    --
    “All right, then, I'll go to hell.” – Huck Finn
    1. Hi,

      Du hast vermutlich einen URL der Gestalt: http://example.com/?reiter=2

      Ja, so ist es.

      In JavaScript gibt es keine globale $_GET-Variable, wie in PHP, die alle URL-Parameter enthält.
      Dafür gibt es in JavaScript das document.location.href-Objekt, dass die gesamten URL beinhaltet unt mit URL. Daraus müsstest du den Parameter reiter=2 selber extrahieren. Dazu gibt es auch schon tausende Helferlein.

      Brauch ich aber doch eigentlich nicht.
      Stell' Dir einfach vor, ich würde grundsätzlich nach Laden des DOM eine Javascriptfunktion ausführen wollen, ganz unabhängig von meinem GET-Array.

      So kompliziert sieht er doch gar nicht aus.

      Ok.

      Klaus

      1. Meine Herren!

        In JavaScript gibt es keine globale $_GET-Variable, wie in PHP, die alle URL-Parameter enthält.
        Dafür gibt es in JavaScript das document.location.href-Objekt, dass die gesamten URL beinhaltet unt mit URL. Daraus müsstest du den Parameter reiter=2 selber extrahieren. Dazu gibt es auch schon tausende Helferlein.

        Brauch ich aber doch eigentlich nicht.
        Stell' Dir einfach vor, ich würde grundsätzlich nach Laden des DOM eine Javascriptfunktion ausführen wollen, ganz unabhängig von meinem GET-Array.

        Ja genauso stell ich mir das vor, und dann liegt es beim JavaScript rauszufinden, welches Tab geöffnet werden soll, oder nicht?
        Sonst verstehe dich das Problem nicht richtig.

        --
        “All right, then, I'll go to hell.” – Huck Finn
        1. Stell' Dir einfach vor, ich würde grundsätzlich nach Laden des DOM eine Javascriptfunktion ausführen wollen, ganz unabhängig von meinem GET-Array.

          Ja genauso stell ich mir das vor, und dann liegt es beim JavaScript rauszufinden, welches Tab geöffnet werden soll, oder nicht?

          Nein. Das hat zu diesem Zeitpunkt php bereits erledigt.

          Sonst verstehe dich das Problem nicht richtig.

          Ich hab Mathias nochmal genauer beschrieben, was ich meine.

          Klaus

  2. Hallo,

    Nun habe ich die (native) Funktion "reiter" entfernt, weil ich das Wechseln der Reiter im restlichen Script über ein Jquery onclick Event ausführe.

    Hmm… was denn nun? Willst du beim Laden der Seite Code ausführen oder beim Klick? Oder beides?

    if ($_GET['reiter'] == 2) {

    echo ("
    <script type="text/javascript">
    reiter('r2','r1');
    </script>
    ");
    }

    
    >   
    > Geht sowas adäquat auch über Jquery?  
      
    Ich fürchte, verstehe dein Problem nicht ganz… Ich hatte schon in <https://forum.selfhtml.org/?t=217953&m=1498895> versucht, das Zusammenspiel von JavaScript und jQuery zu erklären.  
      
    Es scheint mir, das hat mit jQuery nichts zu tun, sondern mit grundlegender JavaScript-Logik. Wenn du eine Code mehrfach bzw. wahlweise ausführen willst, ist es hilfreich, ihn in einer Funktion unterzubringen. Mit oder ohne jQuery.  
      
    
    > Also, wie kann ich den Code  
    >   
    > ~~~javascript
    
    $(\"#r1\").toggle(200);  
    
    > $(\"#r2\").toggle(400);  
    > $(\"#t2\").removeClass(\"deaktiv\");  
    > $(\"#t2\").addClass(\"aktiv\");  
    > $(\"#t1\").removeClass(\"aktiv\");  
    > $(\"#t1\").addClass(\"deaktiv\");  
    > });
    
    

    ausführen, wenn beim Aufruf der Seite $_GET['reiter'] == 2 ist?

    Indem du ihn wieder in eine wiederverwendbare Funktion packst und diese wahlweise beim Laden der Seite ausführst, je nachdem, wie due URL lautet. Das kannst du entweder mit PHP machen (wie bisher) oder auch mit JavaScript (darauf hatte 1UnitedPower hingewiesen).

    Und muß der css-Klassenwechsel so kompliziert sein, wie ich es notiert habe? Die Klasse toggeln hatte nicht die Wirkung, die ich wollte.

    Togglen sollte funktionieren, wenn die Zustände immer konsistent sind (d.h. wenn t1 aktiv ist, muss t2 inaktiv sein, sonst führt das Togglen wieder zu einem falschem Ergebnis).

    Sinnvoller ist es, *eine* »aktiv«-Klasse und keine »deaktiv«-Klasse, sodass nur eine Klasse getoggelt werden muss.

    Grüße
    Mathias

    1. Hi,

      Hmm… was denn nun? Willst du beim Laden der Seite Code ausführen oder beim Klick? Oder beides?

      Beides.

      Der Reiterwechsel kann einem Onclick-Event folgen oder aber einem Serverrequest. Gehe ich über den Server, will ich natürlich gleich auf den Reiter gehen, der den Request abgefeuert hatte. Defaultmäßig wird Reiter 1 geladen, die Seite hat nur 2 Reiter. Steuern will ich das über php.

      Ich fürchte, verstehe dein Problem nicht ganz… Ich hatte schon in https://forum.selfhtml.org/?t=217953&m=1498895 versucht, das Zusammenspiel von JavaScript und jQuery zu erklären.

      Danke, ich hatte es gelesen, ich wußte nicht, ob es hier üblich ist, das innerhalb des Themas rückzuspiegeln oder zu bedanken. Das tue ich aber hiermit. Danke.

      Es scheint mir, das hat mit jQuery nichts zu tun, sondern mit grundlegender JavaScript-Logik. Wenn du eine Code mehrfach bzw. wahlweise ausführen willst, ist es hilfreich, ihn in einer Funktion unterzubringen. Mit oder ohne jQuery.

      Ok. Das soll mein Ansatz sein.

      Geht mit Jquery etwas in der Art wie

        
      function testfunktion(param1,param2) {  
      $(document).ready(function() {  
      $(#param1).fadeIn(400);  
      $(#param0).fadeOut(100);  
      }  
      }  
      
      

      oder auch

        
      function testfunktion() {  
      $(document).ready(function() {  
      $("#test1").fadeIn(400);  
      $("#test0").fadeOut(100);  
      }  
      }  
      
      

      ?

      Indem du ihn wieder in eine wiederverwendbare Funktion packst und diese wahlweise beim Laden der Seite ausführst, je nachdem, wie due URL lautet.

      Genau. Wie geht sowas, wenn man Jquery verwendet?

      Klaus

      1. Hallo,

        function testfunktion(param1,param2) {
        $(document).ready(function() {
        $(#param1).fadeIn(400);
        $(#param0).fadeOut(100);
        }
        }

          
        Das \*kannst\* du so machen.  
          
        `$(document).ready(function() {…})`{:.language-javascript} sorgt dafür, dass die angegebene Funktion nach erfolgreichen Laden des HTML-Codes ausgeführt wird, nicht früher. Intern wird auf den [DOMContentLoaded-Event](http://molily.de/js/event-handling-onload.html) gewartet. Wenn dieser schon eingetreten ist, wird die Funktion sofort ausgeführt.  
          
        Ob das in deinem Fall nötig ist, weiß ich nicht – das hängt davon ab, wann die Funktionen ausgeführt werden und ob das DOM \*vor\* dem script-Element bereits die Element enthält, auf die du zugreifen willst. Wenn ja, dann ist `$(document).ready()`{:.language-javascript} unnötig, wenn nicht, dann ist es nötig, weil dir jQuery sonst leere Resultatlisten zurückliefert, wenn du `$('#foo')`{:.language-javascript} usw. notierst. Es besteht kein Zwang, immer mit `$(document).ready()`{:.language-javascript} zu arbeiten, wenn man jQuery verwendet.  
          
        Beispiel:  
          
        1\. Das Script wird ausgeführt, bevor Element eingelesen wurde. Das Script kann nicht direkt auf das Element zugreifen:  
          
        ~~~html
        <script>  
        [code lang=javascript]console.log( $('#foo').length ); // 0
        

        </script>
        <p id="foo"></p>[/code]

        2. Das Script kommt im DOM nach dem Element, kann also direkt darauf zugreifen. $(document).ready() ist dann nicht zwingend notwendig.

        <p id="foo"></p>  
        <script>  
        [code lang=javascript]console.log( $('#foo').length ); // 1
        

        </script>[/code]

        3. Wenn du $(document).ready() verwendest, ist die Reihenfolge egal:

        <script>  
        [code lang=javascript]$(document).ready(function() {  
          // Diese Funktion wird garantiert erst nach dem vollständigen Einlesen des HTML-Codes ausgeführt  
          console.log( $('#foo').length ); // 1  
        });  
        
        ~~~</script>  
        <p id="foo"></p>[/code]  
          
        Hintergrund:  
        <http://molily.de/js/einbindung.html>  
          
        Mathias
        
        -- 
        [Chaplin.js - JavaScript application architecture on top of Backbone.js](http://chaplinjs.org/)
        
        1. Hallo,

          function testfunktion(param1,param2) {
          $(document).ready(function() {
          $(#param1).fadeIn(400);
          $(#param0).fadeOut(100);
          }
          }

          
          >   
          > Das \*kannst\* du so machen.  
            
          Hi,  
            
          und wie rufe ich sie mittels JQuery auf? Bzw. gebe ihr auch noch Parameter mit? Oder kann ich das dann nur "klassisch" machen?  
            
          Den Rest Deiner Ausführungen habe ich - nein -glaube ich, verstanden zu haben.  
            
          Klaus  
          
          
          1. Hallo,

            und wie rufe ich sie mittels JQuery auf Bzw. gebe ihr auch noch Parameter mit? Oder kann ich das dann nur "klassisch" machen?

            Ja, klar. Du rufst sie auf, wie man eine JavaScript-Funktion nun einmal aufruft:

            funktion(param1, param2, param3);

            Direkt (am Ende des Dokuments, z.B. vor </body>):

            <script>  
            [code lang=javascript]funktion(param1, param2, param3);
            

            </script>[/code]

            Im DOM-Ready-Handler (falls nötig):

            <script>  
            [code lang=javascript]$(document).ready(function() {  
              funktion(param1, param2, param3);  
            });
            

            </script>[/code]

            Im Klick-Handler:

            <script>  
            [code lang=javascript]$('#foo').click(function() {  
              funktion(param1, param2, param3);  
            });
            

            </script>[/code]

            usw.

            Mathias

            1. Hallo Matthias,

              Ja, klar. Du rufst sie auf, wie man eine JavaScript-Funktion nun einmal aufruft:

              Danke für Deine 3 Beispiele.

              Insbesondere zu einem hiervon habe ich eine Nachfrage.

              Im Klick-Handler:

              <script>

              [code lang=javascript]$('#foo').click(function() {
                funktion(param1, param2, param3);
              });

              
              > </script>[/code]  
                
                
              Was nützen mir hier die 3 Parameter? Die kann ich doch auch "hartcodiert" ins eigentliche Javascript eintragen. Was ich meine ist, sie kommen doch nicht wirklich "dymanisch" dort hinein und werden verarbeitet.  
                
              Für mich ist eine Funktion "ein Gerüst an Code, das immer dasselbe macht, nur eben mit verschiedenen Parametern, die von außerhalb der eigentlichen Funktion kommt".  
                
              Das ist aber doch hier dann gar nicht gegeben.  
                
              Beispiel:  
                
              Tabelle mit 1000 Einträgen, wovon jeder Eintrag ein onclick Event abfeuern kann.  
                
              Klassisches jS: Ich hänge den Onclick-Event an ein hierfür geeignetes Tag und steuere eine Funktion an, hierbei übergebe ich die nötigen Parameter, die dem Eintrag entsprechen.  
                
              JQuery: Ich generiere 1000 ".click(function()", sowie 1000 entsprechende IDs innerhalb der Einträge?  
                
              Ist das so gemeint oder verstehe ich das etwas nicht richtig?  
                
              Klaus
              
              1. Hallo,

                Was nützen mir hier die 3 Parameter? Die kann ich doch auch "hartcodiert" ins eigentliche Javascript eintragen. Was ich meine ist, sie kommen doch nicht wirklich "dymanisch" dort hinein und werden verarbeitet.

                Natürlich sind sie an dieser Stelle hartkodiert, was aber nicht ausschließt, dass die Funktion an anderer Stelle mit anderen Parametern aufgerufen wird. Wenn das nie passiert, sind keine Funktionsparameter nötig.

                Für mich ist eine Funktion "ein Gerüst an Code, das immer dasselbe macht, nur eben mit verschiedenen Parametern, die von außerhalb der eigentlichen Funktion kommt".

                Ja, genau.

                Das ist aber doch hier dann gar nicht gegeben.

                Das Beispiel war ja auch rein formal, auf der Ebene lässt sich schwer räsonieren.

                Tabelle mit 1000 Einträgen, wovon jeder Eintrag ein onclick Event abfeuern kann.

                Klassisches jS: Ich hänge den Onclick-Event an ein hierfür geeignetes Tag und steuere eine Funktion an, hierbei übergebe ich die nötigen Parameter, die dem Eintrag entsprechen.

                JQuery: Ich generiere 1000 ".click(function()", sowie 1000 entsprechende IDs innerhalb der Einträge?

                Nein, das wäre keine gute Lösung. Der jQuery-Code kann genauso arbeiten wie das klassische JavaScript. jQuery muss eigentlich nie ineffizienter arbeiten, es sei denn aufgrund von Flexibilität in der Implementierung.

                Man braucht keine tausend IDs hinzuzufügen, damit jQuery die gewünschten Elemente ansprechen kann, und entsprechend händisch 1000 Klick-Handler zu registrieren. jQuery kann Elemente mit CSS-artigen Selektoren auswählen, z.B.

                <table id="tabelle"><tr><td></td></tr></table>

                $('#tabelle td').click(function(event) {  
                  console.log( event.target );  
                });
                

                Dieser Code reicht aus, um alle td-Elemente mit einem Event-Handler zu versorgen. Das ist allerdings noch immer ineffektiv, da nach wie vor soviele Event-Handler registriert werden müssen, wie es td-Elemente gibt. In dem Fall würde man eher Event Delegation verwenden, also die click-Events zentral beim übergeordneten table-Element überwachen. Das ginge mit jQuery so:

                $('#tabelle').on('click', 'td', function(event) {  
                  console.log( event.target );  
                });
                

                … überwacht alle click-Elemente auf td-Elemente innerhalb von #tabelle. Das funktioniert, weil click-Element aufsteigen (Bubbling).

                http://api.jquery.com/on/

                Mathias

                1. Hallo Matthias,

                  danke für Deine Erklärungen. Die bringen mich sehr weiter. (Übrigens schade, daß Deine tolle Doku nicht als PDF verfügbar ist. Oder gibt es eine Möglichkeit, sie so auszudrucken, daß sinnvolle Seitenumbrüche stattfinden?)

                  Natürlich sind sie an dieser Stelle hartkodiert, was aber nicht ausschließt, dass die Funktion an anderer Stelle mit anderen Parametern aufgerufen wird.

                  Aber ein solcher Aufruf muß dann doch zwingenderweise "klassisch" erfolgen, stimmt das?

                  Man braucht keine tausend IDs hinzuzufügen, damit jQuery die gewünschten Elemente ansprechen kann, und entsprechend händisch 1000 Klick-Handler zu registrieren. jQuery kann Elemente mit CSS-artigen Selektoren auswählen,

                  Perfekt. Das wußte ich nicht.

                  <table id="tabelle"><tr><td></td></tr></table>

                  $('#tabelle td').click(function(event) {

                  console.log( event.target );
                  });

                  
                  >   
                  > Dieser Code reicht aus, um alle td-Elemente mit einem Event-Handler zu versorgen. Das ist allerdings noch immer ineffektiv, da nach wie vor soviele Event-Handler registriert werden müssen, wie es td-Elemente gibt.  
                    
                  
                  >   
                  > ~~~javascript
                  
                  $('#tabelle').on('click', 'td', function(event) {  
                  
                  >   console.log( event.target );  
                  > });
                  
                  

                  … überwacht alle click-Elemente auf td-Elemente

                  Genau das hätte ich für Beispiel 1 schon erwartet. Ich versteh momentan nicht, wo mein Denkfehler hierbei ist. (abgesehen davon, daß ich "bind" anstelle von "on" erwartet hatte, was grade aber unwichtig ist).

                  Wichtiger ist, daß ich den Unterschied von Bsp.1 zu Bsp. 2 nicht überreiße.

                  Klaus

                  1. Meine Herren!

                    Aber ein solcher Aufruf muß dann doch zwingenderweise "klassisch" erfolgen, stimmt das?

                    Ja, dass du jQuery nicht von JavaScript trennen kannst, hast du verstanden oder?

                    Funktionsaufrufe finden immer "klassisch" statt. Genauso, wie ein if-Statement immer klassisch stattfindet.

                    Funktionsaufrufe geschehen immer auf eine der drei folgenden Arten:

                    funktion();  
                    funktion.call();  
                    funktion.apply();  
                    
                    

                    (Exoten, wie setTimeout einmal außer Acht gelassen.)

                    Eine andere Methode eine Funktion aufzurufen gibt es nicht, die kann auch jQuery nicht neu erfinden.

                    Was jQuery aber kann, ist eine Callback-Funktion entgegen nehmen und sie dann aufrufen, wenn jQuery es für nötig hält. So geschieht es zum Beispiel, wenn ein Event-Handler registriert wird. Beispielweise:

                    $( document ).ready( callback );  
                    // oder  
                    $( 'div' ).click( callback );  
                      
                    function callback () { /* … */ };
                    

                    Diese Funktion wird von uns nicht selber aufgerufen, stattdessen werden sie jQuery bekannt gemacht. Aber unter der Haube wird jQuery diese Funktionen irgendwo mit einem der drei oben genannten Methoden aufrufen.

                    Das Prinzip nennt sich "inversion of control". Wir sagen jQuery sinngemäß "Hier du weißt am besten, wann diese Funktion aufgerufen werden muss, also mach du das für uns".

                    Wenn kein konkreter Grund vorliegt den Methoden-Aufruf an jQuery zu delegieren, etwa, weil wir selber genau wissen, wann unsere Funktion aufgerufen werden muss, dann können wir keinen Nutzen aus diesem Prinzip ziehen und rufen die Funktion selber "klassisch" auf.

                    --
                    “All right, then, I'll go to hell.” – Huck Finn
                  2. Wichtiger ist, daß ich den Unterschied von Bsp.1 zu Bsp. 2 nicht überreiße.

                    $('#tabelle td') erzeugt eine "Liste" mit allen td-Elementen die Kind vom Element mit id "tabelle" sind.
                    $('#tabelle td').click(... registriert an allen diesen td-Elementen einen Eventhandler, der durch "click" getriggert wird
                    $('#tabelle) erzeugt eine "Liste" mit einem Element, dem mit der id "tabelle"
                    $('#tabelle').on('click', 'td', ... registriert an diesem einen Element einen Eventhandler, der durch "click" getriggert wird und prüft, ob da click-Event ursprünglich von einem td Element kommt und hochgebubbelt wurde(event.target ist ein td-Element).

                  3. Hallo,

                    jQuery kann Elemente mit CSS-artigen Selektoren auswählen,

                    Perfekt. Das wußte ich nicht.

                    Ich schlage vor, dass du dir ein Einführungsbuch zu jQuery durchliest, denn das sind wichtige Grundlagen, ohne die man eigentlich nicht sinnvoll mit jQuery arbeiten kann. Sie hier gemeinsam zu erarbeiten ist ein bisschen langwierig. ;)

                    jQuery arbeitet mit dem grundlegenden Datentyp einer Elementliste (DOM-Elementknoten). Insofern verhält sich ein jQuery-Objekt wie ein Array. Die verschiedenen Methoden durchlaufen die Elemente in der Liste und machen irgendetwas damit.

                    (abgesehen davon, daß ich "bind" anstelle von "on" erwartet hatte, was grade aber unwichtig ist).

                    »bind« wurde in jQuery 1.7 (November 2011) durch das vielseitigere »on« ersetzt. bind sollte nicht mehr verwendet werden.

                    Mathias