JQuery und AJAX

JQuery hat es erheblich vereinfacht, an zentraler Stelle Event Handler für diverse Ereignisse zu erstellen. Wenn man mit AJAX arbeitet, wird man aber rasch darüber stolpern, dass ein Handler wie $(‘#meineId’).click(… nicht funktioniert, wenn das Element mit der Id meineId mit AJAX erst nachträglich generiert wird und deshalb beim ersten Laden noch gar nicht existiert.

Seit JQuery Version 1.3 kann man statt .click nun das Event Handler Attachment .live(even type, handler) benutzen. Live reagiert auf alle Elemente, auch auf solche, die erst in Zukunft dynamisch zu einer Seite hinzugefügt werden, sei es durch AJAX requests oder sei es durch JavaScript.

Das folgende Beispiel zeigt die Kombination von JQuery’s .live mit AJAX. Für die serverseitige Programmierung verwende ich Grails in der Version 1.1.1 und JQuery in der Version 1.3.2. Die Lösung besteht aus zwei Teilen: Erstens der Webseite mit dem JQuery-Event-Handler und dem AJAX-Aufruf und zweitens dem serverseitigen Handler für den AJAX-Aufruf.

Die Aufgabenstellung ist denkbar einfach: Ein Klick auf einen Link macht einen AJAX-Call. Dieser hängt einen neuen Link an das Dokument. Bei einem Klick auf diesen neuen, dynamisch erzeugten Link wird der JQuery-Event-Handler aktiviert. Er liest die zufällig erzeugte Zahl aus, die dem Link als Parameter mitgegeben wurde.

Schauen wir uns zuerst die Webseite an:

<%@ page contentType="text/html;charset=UTF-8" %>

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="layout" content="main" />
    <!-- 1. JQuery library import -->
    <g:javascript library="jquery"/>
    <title>AJAX and event handler attachment with live</title>
    <style type="text/css">
    </style>
    <script language="JavaScript">
      <!--
      $(document).ready(function() {

        // 2. dynamic click handler for content generated later by AJAX
        $(".dynamiclink").live('click', function() {
          var url = $(this).attr('href');
          var position = url.lastIndexOf("=");
          var zahl = url.substr(position + 1);
          $(this).attr('href', 'javascript: void(0)');

          alert("Parameter zahl: " + zahl);
        });
      });

      //-->
    </script>
  </head>

  <body>
    <div class="body">
      <h1>${title} - ${subtitle}</h1>

      <p id="ajaxlinks" class="ajaxlinks">
        <!-- 3. grails handler for AJAX call -->
        <a id="link1" href="javascript: void(0)"
          onclick="${remoteFunction(action:'remoteHtmlAjax_and_live',
            update:'content')}">
          Update screen
        </a><br/>
      </p>
      <!-- 4. div element as container for the generated link -->
      <div id="content">
      </div>
    </div>
  </body>
</html>

Hier steckt die Lösung in den 4 fett markierten Teilen:

  1. Import der JQuery Library  (mindestens Version 1.3)
  2. JQuery-Event-Handler für das Click-Event auf allen dynamisch generierten Elementen mit der Klasse “dynamiclink”: Wichtig ist hier, dass .click durch .live(‘click’, … ersetzt wird. Nur so reagiert der Handler auch auf Elemente, die erst nach dem Laden der Seite entstehen.
  3. serverseitiger Grails-Befehl für die Erzeugung des Links mit dem AJAX-Aufruf: Der neu erzeugte Inhalt wird im <div>-Tag mit der id content angezeigt.
  4. Container-Element, in das der dynamisch erzeugte Link eingefügt wird

Lassen Sie sich nicht dadurch verwirren, dass das $-Zeichen hier zwei verschiedene Bedeutungen hat.

  • In Punkt 2 ist es Teil des Selektors von JQuery (also clientseitig), mit dem das Element für den Click-Handler ausgewählt wird
  • In Punkt 3 ist es dagegen ein serverseitiger Grails-Befehl

Nun fehlt uns eigentlich nur noch der serverseitige AJAX-Handler. Er steckt in einer Controller-Datei, wird in der Scriptsprache Groovy geschrieben und ist geradezu peinlich einfach:

  def remoteHtmlAjax_and_live = {
    int zahl = Math.round(Math.random() * 1000) + 1
    def html = """<a class=\"dynamiclink\"
      href=\"/ajax/jquery/ajax_and_live?zahl=$zahl\">$zahl</a><br />"""
    render html
  }

Diese Zeilen erzeugen eine Zufallszahl und einen HTML-Link, der als Parameter die Zufallszahl erzeugt. Damit sind wir am Ende unseres kleinen Beispiels.

Links:

<%@ page contentType=”text/html;charset=UTF-8″ %>

<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″>
<meta name=”layout” content=”main” />
<g:javascript library=”jquery”/>
<g:set var=”subtitle” value=”AJAX and event handler attachment with live” />
<title>${title} – ${subtitle}</title>
<style type=”text/css”>
</style>
<script language=”JavaScript”>
<!–

$(document).ready(function() {

//dynamic click handler for content generated later by AJAX
$(“.dynamiclink”).live(‘click’, function() {
var url = $(this).attr(‘href’);
var position = url.lastIndexOf(“=”);
var zahl = url.substr(position + 1);
$(this).attr(‘href’, ‘javascript: void(0)’);

alert(“Parameter zahl: ” + zahl);
});
});

//–>
</script>
</head>

<body>
<div class=”body”>
<h1>${title} – ${subtitle}</h1>

<p id=”ajaxlinks” class=”ajaxlinks”>
<a id=”link1″ href=”javascript: void(0)”
onclick=”${remoteFunction(action:’remoteHtmlAjax_and_live’, update:’content’)}”>
Update screen
</a><br/>
</p>
<div id=”content”>
</div>
</div>
</body>
</html>

Comments are closed.