{"id":60,"date":"2010-02-05T16:35:49","date_gmt":"2010-02-05T16:35:49","guid":{"rendered":"http:\/\/localhost\/wordpress\/?p=60"},"modified":"2010-06-03T13:04:18","modified_gmt":"2010-06-03T13:04:18","slug":"jquery-und-ajax","status":"publish","type":"post","link":"https:\/\/blog.ecotronics.ch\/wordpress\/?p=60","title":{"rendered":"JQuery und AJAX"},"content":{"rendered":"<p><strong>JQuery <\/strong>hat es erheblich vereinfacht, <strong>an zentraler Stelle Event Handler f\u00fcr diverse Ereignisse<\/strong> zu erstellen. Wenn man mit <strong>AJAX <\/strong>arbeitet, wird man aber rasch dar\u00fcber stolpern, dass ein Handler wie $(&#8216;#meineId&#8217;).click(&#8230; nicht funktioniert, wenn das Element mit der Id meineId mit AJAX erst <strong>nachtr\u00e4glich generiert<\/strong> wird und deshalb beim ersten Laden noch gar nicht existiert.<\/p>\n<p>Seit JQuery Version 1.3 kann man statt .click nun das <strong>Event Handler Attachment <a href=\"http:\/\/api.jquery.com\/live\/\" target=\"_blank\">.live(even type, handler)<\/a><\/strong> benutzen. Live reagiert auf alle Elemente, auch auf solche, die erst in Zukunft dynamisch zu einer Seite hinzugef\u00fcgt werden, sei es durch AJAX requests oder sei es durch JavaScript.<\/p>\n<p>Das folgende Beispiel zeigt die Kombination von JQuery&#8217;s .live mit AJAX. F\u00fcr die serverseitige Programmierung verwende ich <strong>Grails <\/strong>in der <strong>Version 1.1.1<\/strong> und <strong>JQuery <\/strong>in der <strong>Version 1.3.2<\/strong>. Die L\u00f6sung besteht aus zwei Teilen: Erstens der Webseite mit dem JQuery-Event-Handler und dem AJAX-Aufruf und zweitens dem serverseitigen Handler f\u00fcr den AJAX-Aufruf.<\/p>\n<p>Die <strong>Aufgabenstellung <\/strong>ist denkbar einfach: Ein Klick auf einen Link macht einen AJAX-Call. Dieser h\u00e4ngt 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\u00e4llig erzeugte Zahl aus, die dem Link als Parameter mitgegeben wurde.<\/p>\n<p>Schauen wir uns zuerst die Webseite an:<\/p>\n<pre>&lt;%@ page contentType=\"text\/html;charset=UTF-8\" %&gt;\r\n\r\n&lt;html&gt;\r\n  &lt;head&gt;\r\n    &lt;meta http-equiv=\"Content-Type\" content=\"text\/html; charset=UTF-8\"&gt;\r\n    &lt;meta name=\"layout\" content=\"main\" \/&gt;\r\n    &lt;!-- 1. JQuery library import --&gt;\r\n<strong>    &lt;g:javascript library=\"jquery\"\/&gt;\r\n<\/strong>    &lt;title&gt;AJAX and event handler attachment with live&lt;\/title&gt;\r\n    &lt;style type=\"text\/css\"&gt;\r\n    &lt;\/style&gt;\r\n    &lt;script language=\"JavaScript\"&gt;\r\n      &lt;!--\r\n      $(document).ready(function() {\r\n\r\n        \/\/ 2. dynamic click handler for content generated later by AJAX\r\n<strong>        <span style=\"color: #ff0000;\">$(\".dynamiclink\").live('click', function() <\/span>{\r\n          var url = $(this).attr('href');\r\n          var position = url.lastIndexOf(\"=\");\r\n          var zahl = url.substr(position + 1);\r\n          $(this).attr('href', 'javascript: void(0)');\r\n\r\n          alert(\"Parameter zahl: \" + zahl);\r\n<\/strong>        });\r\n      });\r\n\r\n      \/\/--&gt;\r\n    &lt;\/script&gt;\r\n  &lt;\/head&gt;\r\n\r\n  &lt;body&gt;\r\n    &lt;div class=\"body\"&gt;\r\n      &lt;h1&gt;${title} - ${subtitle}&lt;\/h1&gt;\r\n\r\n      &lt;p id=\"ajaxlinks\" class=\"ajaxlinks\"&gt;\r\n        &lt;!-- 3. grails handler for AJAX call --&gt;\r\n        &lt;a id=\"link1\" href=\"javascript: void(0)\"\r\n          <strong>onclick=\"${remoteFunction(action:'remoteHtmlAjax_and_live',\r\n            update:'<span style=\"color: #0000ff;\">content<\/span>')}\"&gt;<\/strong>\r\n          Update screen\r\n        &lt;\/a&gt;&lt;br\/&gt;\r\n      &lt;\/p&gt;\r\n      &lt;!-- 4. div element as container for the generated link --&gt;\r\n      <strong>&lt;div id=\"<span style=\"color: #0000ff;\">content<\/span>\"&gt;\r\n      &lt;\/div&gt;<\/strong>\r\n    &lt;\/div&gt;\r\n  &lt;\/body&gt;\r\n&lt;\/html&gt;<\/pre>\n<p>Hier steckt die L\u00f6sung in den 4 fett markierten Teilen:<\/p>\n<ol>\n<li>Import der JQuery Library\u00a0 (mindestens Version 1.3)<\/li>\n<li>JQuery-Event-Handler f\u00fcr das Click-Event auf allen dynamisch generierten Elementen mit der Klasse &#8220;dynamiclink&#8221;: Wichtig ist hier, dass .click durch <strong>.live(&#8216;click&#8217;, &#8230; <\/strong>ersetzt wird. Nur so reagiert der Handler auch auf Elemente, die erst nach dem Laden der Seite entstehen.<\/li>\n<li>serverseitiger Grails-Befehl f\u00fcr die Erzeugung des Links mit dem AJAX-Aufruf: Der neu erzeugte Inhalt wird im &lt;div&gt;-Tag mit der id content angezeigt.<\/li>\n<li>Container-Element, in das der dynamisch erzeugte Link eingef\u00fcgt wird<\/li>\n<\/ol>\n<p>Lassen Sie sich nicht dadurch verwirren, dass das <strong>$-Zeichen <\/strong>hier zwei verschiedene Bedeutungen hat.<\/p>\n<ul>\n<li>In Punkt 2 ist es Teil des Selektors von <strong>JQuery (also clientseitig)<\/strong>, mit dem das Element f\u00fcr den Click-Handler ausgew\u00e4hlt wird<\/li>\n<li>In Punkt 3 ist es dagegen ein <strong>serverseitiger Grails-Befehl<\/strong><\/li>\n<\/ul>\n<p>Nun fehlt uns eigentlich nur noch der serverseitige <strong>AJAX-Handler<\/strong>. Er steckt in einer <strong>Controller<\/strong>-Datei, wird in der Scriptsprache <strong>Groovy <\/strong>geschrieben und ist geradezu peinlich einfach:<\/p>\n<pre>  def remoteHtmlAjax_and_live = {\r\n    int zahl = Math.round(Math.random() * 1000) + 1\r\n    def html = \"\"\"&lt;a class=\\\"dynamiclink\\\"\r\n      href=\\\"\/ajax\/jquery\/ajax_and_live?zahl=$zahl\\\"&gt;$zahl&lt;\/a&gt;&lt;br \/&gt;\"\"\"\r\n    render html\r\n  }<\/pre>\n<p>Diese Zeilen erzeugen eine Zufallszahl und einen HTML-Link, der als Parameter die Zufallszahl erzeugt. Damit sind wir am Ende unseres kleinen Beispiels.<\/p>\n<p><strong>Links:<\/strong><\/p>\n<ul>\n<li><a href=\"http:\/\/grails.codehaus.org\/\" target=\"_blank\">Grails<\/a><\/li>\n<li><a href=\"http:\/\/jquery.com\" target=\"_blank\">JQuery<\/a><\/li>\n<\/ul>\n<div id=\"_mcePaste\" style=\"overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;\">&lt;%@ page contentType=&#8221;text\/html;charset=UTF-8&#8243; %&gt;<\/p>\n<p>&lt;html&gt;<br \/>\n&lt;head&gt;<br \/>\n&lt;meta http-equiv=&#8221;Content-Type&#8221; content=&#8221;text\/html; charset=UTF-8&#8243;&gt;<br \/>\n&lt;meta name=&#8221;layout&#8221; content=&#8221;main&#8221; \/&gt;<br \/>\n&lt;g:javascript library=&#8221;jquery&#8221;\/&gt;<br \/>\n&lt;g:set var=&#8221;subtitle&#8221; value=&#8221;AJAX and event handler attachment with live&#8221; \/&gt;<br \/>\n&lt;title&gt;${title} &#8211; ${subtitle}&lt;\/title&gt;<br \/>\n&lt;style type=&#8221;text\/css&#8221;&gt;<br \/>\n&lt;\/style&gt;<br \/>\n&lt;script language=&#8221;JavaScript&#8221;&gt;<br \/>\n&lt;!&#8211;<\/p>\n<p>$(document).ready(function() {<\/p>\n<p>\/\/dynamic click handler for content generated later by AJAX<br \/>\n$(&#8220;.dynamiclink&#8221;).live(&#8216;click&#8217;, function() {<br \/>\nvar url = $(this).attr(&#8216;href&#8217;);<br \/>\nvar position = url.lastIndexOf(&#8220;=&#8221;);<br \/>\nvar zahl = url.substr(position + 1);<br \/>\n$(this).attr(&#8216;href&#8217;, &#8216;javascript: void(0)&#8217;);<\/p>\n<p>alert(&#8220;Parameter zahl: &#8221; + zahl);<br \/>\n});<br \/>\n});<\/p>\n<p>\/\/&#8211;&gt;<br \/>\n&lt;\/script&gt;<br \/>\n&lt;\/head&gt;<\/p>\n<p>&lt;body&gt;<br \/>\n&lt;div class=&#8221;body&#8221;&gt;<br \/>\n&lt;h1&gt;${title} &#8211; ${subtitle}&lt;\/h1&gt;<\/p>\n<p>&lt;p id=&#8221;ajaxlinks&#8221; class=&#8221;ajaxlinks&#8221;&gt;<br \/>\n&lt;a id=&#8221;link1&#8243; href=&#8221;javascript: void(0)&#8221;<br \/>\nonclick=&#8221;${remoteFunction(action:&#8217;remoteHtmlAjax_and_live&#8217;, update:&#8217;content&#8217;)}&#8221;&gt;<br \/>\nUpdate screen<br \/>\n&lt;\/a&gt;&lt;br\/&gt;<br \/>\n&lt;\/p&gt;<br \/>\n&lt;div id=&#8221;content&#8221;&gt;<br \/>\n&lt;\/div&gt;<br \/>\n&lt;\/div&gt;<br \/>\n&lt;\/body&gt;<br \/>\n&lt;\/html&gt;<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>JQuery hat es erheblich vereinfacht, an zentraler Stelle Event Handler f\u00fcr diverse Ereignisse zu erstellen. Wenn man mit AJAX arbeitet, wird man aber rasch dar\u00fcber stolpern, dass ein Handler wie $(&#8216;#meineId&#8217;).click(&#8230; nicht funktioniert, wenn das Element mit der Id meineId mit AJAX erst nachtr\u00e4glich generiert wird und deshalb beim ersten Laden noch gar nicht existiert.<\/p>\n<p> [&#8230;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[36,35],"tags":[30,31,29,28,32,33],"_links":{"self":[{"href":"https:\/\/blog.ecotronics.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/60"}],"collection":[{"href":"https:\/\/blog.ecotronics.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.ecotronics.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.ecotronics.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.ecotronics.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=60"}],"version-history":[{"count":17,"href":"https:\/\/blog.ecotronics.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/60\/revisions"}],"predecessor-version":[{"id":62,"href":"https:\/\/blog.ecotronics.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/60\/revisions\/62"}],"wp:attachment":[{"href":"https:\/\/blog.ecotronics.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=60"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.ecotronics.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=60"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.ecotronics.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=60"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}