Ajax 101 Workshop

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

7 comments

Comments 1 - 7 of 7 previous next Post a comment

Post a comment
Embed Video
Edit your comment Cancel

183 Favorites & 5 Groups

Ajax 101 Workshop - Presentation Transcript

  1. Ajax 101 Introduction to DHTML & Ajax Development Bill W. Scott,Y! Ajax Evangelist 1
  2. What is Ajax? • AJAX = Asynchronous JavaScript and XML • Strict definition is using XMLHttpRequest (XHR) to retrieve XML within a web page • Ajax = The set of technologies that allow web applications to provide rich interaction, just-in-time information and dynamic interfaces without required page refresh • The Secret Sauce • Ajax = XHR + DHTML (HTML, CSS, JavaScript) + Rich design Ajax 101 2 2
  3. Ajax: Before & After Example Ajax 101 3 3
  4. Classic Web Http Response Server Http Request Ajax 101 4 4
  5. With Ajax Ajax 101 5 5
  6. With Ajax onreadystatechange XHR Server Object send() Ajax 101 5 5
  7. Other Techniques • Hidden IFrame • <img> src • <script> src hack • CSS href hack • JS to faceless Java applets • JS to faceless Flash • NO CONTENT Response • Cookies Ajax 101 6 6
  8. Operation Trigger Update Learning Ajax • Learning Ajax, means understanding • Triggers (event or timer) • Operations (ajax xhr) • Updating (dom) Triggering Using XHR Updating Events & for Ajax the DOM Timers Operations Ajax 101 7 7
  9. Operation. Using XHR Ajax 101 8 8
  10. Ajax Simple Ajax ‘Hello World’ XHR Ajax 101 9 9
  11. Ajax Simple Ajax ‘Hello World’ XHR <h2>Ajax Hello World</h2> <p>Clicking the link below will use XHR to fetch the data and then show the result in the box below.</p> <span class="ajaxlink" onclick="makeRequest('test.xml')"> Make an ajax request for data </span> <div id="helloArea"></div> /index.html Ajax 101 9 9
  12. Ajax Simple Ajax ‘Hello World’ XHR <?xml version="1.0" ?> request <root> XHR This data was brought Object to you by Ajax! data </root> /response.xml response <h2>Ajax Hello World</h2> <p>Clicking the link below will use XHR to fetch the data and then show the result in the box below.</p> <span class="ajaxlink" onclick="makeRequest('test.xml')"> Make an ajax request for data </span> <div id="helloArea"></div> /index.html • Clicking the link makes an XHR request • Response is inserted into the area outlined in blue Ajax 101 9 9
  13. Ajax Ajax How To XHR 1. Create a request object 2. Make the request 3. Handle the response Ajax 101 10 10
  14. Ajax Ajax How To XHR 1. Create a request object request 2. Make the request XHR Object 3. Handle the response response Ajax 101 10 10
  15. 1. Create a Request Object Ajax XHR var xhr = null; if (window.XMLHttpRequest) { browser is mozilla or safari or opera then create a XMLHttpRequest(); xhr = newnew XMLHttpRequest xhr.overrideMimeType(‘text/xml’); otherwise it is IE then } else if (window.ActiveXObject) { create a ActiveXObject(“Microsoft.XMLHTTP”); xhr = newnew ActiveXObject otherwise } else { alert(“Perhaps your browser doesn’t support Ajax.”); error - browser does not support XMLHttpRequest } • IE5, 5.5, 6 implements XHR as an ActiveX object (Msxm12.XMLHTTP/Microsoft.XMLHTTP) • Mozilla 1.0+, Safari 1.2+, Opera 8+, IE7 provide XMLHttpRequest object natively • All XHR objects have same methods & properties Ajax 101 11 11
  16. 1. Create a Request Object Ajax XHR var xhr = null; if (window.XMLHttpRequest) { xhr = new XMLHttpRequest(); xhr.overrideMimeType(‘text/xml’); } else if (window.ActiveXObject) { xhr = new ActiveXObject(“Microsoft.XMLHTTP”); } else { alert(“Perhaps your browser doesn’t support Ajax.”); } • IE5, 5.5, 6 implements XHR as an ActiveX object (Msxm12.XMLHTTP/Microsoft.XMLHTTP) • Mozilla 1.0+, Safari 1.2+, Opera 8+, IE7 provide XMLHttpRequest object natively • All XHR objects have same methods & properties Ajax 101 11 11
  17. XHR Methods 1. Create Method Description open(“method”, “url”, [, asynchFlag [, Sets up the request object for sending a “username” [, “password”]]]) request send(content) Sends the request to the server. Can be null. abort() Stops the request. getAllResponseHeaders() Returns all response headers for the HTTP request as key/value pairs. getReponseHeader(“header”) Returns the string value of the specified header. setRequestHeader(“header”, “value”) Sets the specified header to the supplied value. Source: Foundations of Ajax - APress Ajax 101 12 12
  18. XHR Properties 1. Create Property Description onreadystatechange The event handler that fires at every state change. readystate The state of the request: 0=uninitialized, 1=loading, 2=loaded, 3=interactive, 4=complete responseText The response from the server as a text string responseXML The response from the server as an XML document status The HTTP status code from the server for the request object: 200: Ok; 201: Created; 400: bad request, 403: Forbidden; 500: internal sever error statusText The text version of the HTTP status code Ajax 101 13 13
  19. 2. Make the Request Ajax XHR set onreadystatechange tohandleAjaxResponse;- handleAjaxResponse xhr.onreadystatechange = callback function open a request ‘response.xml’, xhr.open(‘GET’,on the xhr objecttrue); send the request through the xhr object xhr.send(null); • The JavaScript function handleAjaxResponse will be invoked when the readystate property changes on the XHR object server must be accessible via relative url X • Same site rule response √ • ‘GET’ or ‘POST’ XHR Object • Asynchronous flag request X Ajax 101 14 14
  20. 2. Make the Request Ajax XHR xhr.onreadystatechange = handleAjaxResponse; xhr.open(‘GET’, ‘response.xml’, true); xhr.send(null); • The JavaScript function handleAjaxResponse will be invoked when the readystate property changes on the XHR object server must be accessible via relative url X • Same site rule response √ • ‘GET’ or ‘POST’ XHR Object • Asynchronous flag request X Ajax 101 14 14
  21. Steps 1 & 2:YUI Syntactical Sugar Ajax XHR var request = YAHOO.util.Connect.asyncRequest('GET', ‘response.xml’, { success:handleAjaxResponse, failure:handleFailure }, null); • Callback sets up response • success, failure, timeout callbacks • scope • upload • any user-defined parameters • or just pass a function Ajax 101 15 15
  22. 3. Parse the Response Ajax 4. Response XHR function handleAjaxResponse() handleAjaxResponse { begin if ((xhr.readystate == 4) && (xhr.status == 200)) { response is valid then var doc = xhr.responseXML; get responseXML var rootNode = doc.getElementsByTagName('root').item(0); get var helloArea = document.getElementById("helloArea"); get on the page helloArea.innerHTML=rootNode.firstChild.data; stuff the rootNode value into the helloArea DIV }endif } end • readystate values 0 – Uninitialized 1 – Loading 2 – Loaded 3 – Interactive 4 – Completed Ajax 101 16 16
  23. 3. Parse the Response Ajax 4. Response XHR function handleAjaxResponse() { if ((xhr.readystate == 4) && (xhr.status == 200)) { var doc = xhr.responseXML; var rootNode = doc.getElementsByTagName('root').item(0); var helloArea = document.getElementById("helloArea"); helloArea.innerHTML=rootNode.firstChild.data; } } • readystate values 0 – Uninitialized 1 – Loading 2 – Loaded 3 – Interactive 4 – Completed Ajax 101 16 16
  24. Step 3 with YUI Connection Manager Ajax XHR function handleAjaxResponse(response, callbackObj) { var doc = response.responseXML; var rootNode = doc.getElementsByTagName('root').item(0); var helloArea = document.getElementById("helloArea"); helloArea.innerHTML=rootNode.firstChild.data; } Ajax 101 17 17
  25. 3. Parse the Response: Handling an XML Response on the Client Ajax XHR • Use XHR property responseXML to get the response as an XML DOM (XmlDocument) • Use standard JavaScript DOM methods • Mozilla, Safari, Opera & IE support a common set of methods and properties • Watch out for IE only stuff (e.g., children property) • Watch out for whitespace issues • Other options • Use XML library for JS (e.g., XML for <script>) Ajax 101 18 18
  26. 3. Parse the Response: Xml Document API 4. Response Property/Method Description documentElement Returns the root element of the document firstChild Is the first element within another element (the first child of the current node) lastChild Is the last element within another element (the last child of the current node) nextSibling Is the next element in the same nested level as the current one previousSibling Is the previous element in the same nested level as the current one nodeValue The value of a document element getElementsByTagName Used to place all elements into an object ???????? Ajax 101 19 19
  27. 3. Parse the Response: A little more parsing. 4. Response <?xml version="1.0" ?> <root> <contents> This data was brought to you by Ajax! </contents> <style> height:40px;width:250px;margin-top:20px;padding:20px;border:8px solid red; </style> </root> Ajax 101 20 20
  28. 3. Parse the Response: A little more parsing. 4. Response <?xml version="1.0" ?> <root> <contents> This data was brought to you by Ajax! </contents> <style> height:40px;width:250px;margin-top:20px;padding:20px;border:8px solid red; </style> </root> function handleAjaxResponse() { if (xhr.readyState == 4) { if (xhr.status == 200) { var response = xhr.responseXML.documentElement; var content = response.getElementsByTagName('contents')[0].firstChild.data; var style = response.getElementsByTagName('style')[0].firstChild.data; var helloArea = document.getElementById("helloArea"); helloArea.innerHTML=content; helloArea.style.cssText=style; } else { alert('There was a problem with the request.'); } } } Ajax 101 20 20
  29. 3. Parse the Response: A little more parsing. 4. Response <?xml version="1.0" ?> <root> <contents> This data was brought to you by Ajax! </contents> <style> height:40px;width:250px;margin-top:20px;padding:20px;border:8px solid red; </style> </root> function handleAjaxResponse() { if (xhr.readyState == 4) { if (xhr.status == 200) { var response = xhr.responseXML.documentElement; var content = response.getElementsByTagName('contents')[0].firstChild.data; var style = response.getElementsByTagName('style')[0].firstChild.data; var helloArea = document.getElementById("helloArea"); helloArea.innerHTML=content; helloArea.style.cssText=style; } else { alert('There was a problem with the request.'); } } } Ajax 101 20 20
  30. 3. Parse the Response: A little more parsing. 4. Response <?xml version="1.0" ?> <root> <contents> This data was brought to you by Ajax! </contents> <style> height:40px;width:250px;margin-top:20px;padding:20px;border:8px solid red; </style> </root> function handleAjaxResponse() { if (xhr.readyState == 4) { if (xhr.status == 200) { var response = xhr.responseXML.documentElement; var content = response.getElementsByTagName('contents')[0].firstChild.data; var style = response.getElementsByTagName('style')[0].firstChild.data; var helloArea = document.getElementById("helloArea"); helloArea.innerHTML=content; helloArea.style.cssText=style; } else { alert('There was a problem with the request.'); } } } Ajax 101 20 20
  31. Handling the Response Ajax • Two types: responseText, responseXML XHR • Many forms: data, html, JS, JSON text xml data data html html response XHR Object JS JS request json Ajax 101 21 21
  32. Handling the Response: Server-Side-GUI Method Ajax • JavaScript generated on server-side XHR • JavaScript is eval’ed on client side to generate GUI • Dangerous! text xml data data html html response XHR Object interface JS JS request code json Ajax 101 22 22
  33. Handling the Response: Direct-HTML Method Ajax XHR • HTML generated on server side • Stuffed into innerHTML of DOM element text xml data data html html innerHTML response XHR Object JS JS request json Ajax 101 23 23
  34. Handling the Response: Direct-HTML Method Ajax XHR Ajax 101 24 24
  35. Handling the Response: Direct-HTML Method Ajax XHR // var helloArea = YAHOO.util.Dom.get(“hello-area”); var helloArea = document.getElementById("hello-area"); helloArea.innerHTML=”<p>Hello <em>World</em></p>”; Ajax 101 24 24
  36. Handling the Response: Direct-HTML Method Ajax XHR // var helloArea = YAHOO.util.Dom.get(“hello-area”); var helloArea = document.getElementById("hello-area"); helloArea.innerHTML=”<p>Hello <em>World</em></p>”; <p>A message will be inserted below:</p> <div id=”hello-area” style="height:20px;width: 220px;margin-top:8px;padding:4px;border:1px solid Ajax 101 24 24
  37. Handling the Response: Direct-HTML Method Ajax XHR // var helloArea = YAHOO.util.Dom.get(“hello-area”); var helloArea = document.getElementById("hello-area"); helloArea.innerHTML=”<p>Hello <em>World</em></p>”; <p>A message will be inserted below:</p> <div id=”hello-area” style="height:20px;width: 220px;margin-top:8px;padding:4px;border:1px solid Ajax 101 24 24
  38. Handling the Response:View-From-Model Method Ajax XHR • Model data generated on server side • w3c DOM elements created from model data • Substitute model data into HTML strings and insert via innerHTML text xml data data model html html response XHR Object JS JS request json Ajax 101 25 25
  39. W3C Create Nodes Ajax XHR Ajax 101 26 26
  40. W3C Create Nodes Ajax XHR // var helloArea = YAHOO.util.Dom.get(“hello-area”); var helloArea = document.getElementById("hello-area"); var para = document.createElement("p"); var paraText = document.createTextNode("Hello "); var em = document.createElement("em"); var emText = document.createTextNode("World"); helloArea.appendChild(para); para.appendChild(paraText); para.appendChild(em); em.appendChild(emText); Ajax 101 26 26
  41. W3C Create Nodes Ajax XHR // var helloArea = YAHOO.util.Dom.get(“hello-area”); var helloArea = document.getElementById("hello-area"); var para = document.createElement("p"); var paraText = document.createTextNode("Hello "); var em = document.createElement("em"); var emText = document.createTextNode("World"); helloArea.appendChild(para); para.appendChild(paraText); para.appendChild(em); em.appendChild(emText); <p>A message will be inserted below:</p> <div id=”hello-area” style="height:20px;width: 220px;margin-top:8px;padding:4px;border:1px solid Ajax 101 26 26
  42. W3C Create Nodes Ajax XHR // var helloArea = YAHOO.util.Dom.get(“hello-area”); var helloArea = document.getElementById("hello-area"); var para = document.createElement("p"); var paraText = document.createTextNode("Hello "); var em = document.createElement("em"); var emText = document.createTextNode("World"); helloArea.appendChild(para); para.appendChild(paraText); para.appendChild(em); em.appendChild(emText); <p>A message will be inserted below:</p> <div id=”hello-area” style="height:20px;width: 220px;margin-top:8px;padding:4px;border:1px solid Ajax 101 26 26
  43. Ajax JSON XHR • JavaScript supports several string based notations • Allows the basic types to be represented as string literals • Strings are easy to pass over the wire • JSON (JavaScript Object Notation - json.org) Ajax 101 27 27
  44. JSON Response: Object Literal Ajax XHR {"name": "Jack B. Nimble", "at large": true, "grade": "A", "level": 3} name Jack B. Nimble at large true grade A level 3 Ajax 101 28 28
  45. JSON Response: Array Literal Ajax XHR ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] array of 7 named days [ [0, -1, 0], [1, 0, 0], [0, 0, 1] ] 3x3 array Ajax 101 29 29
  46. JSON Response: JSON is JavaScript Ajax XHR • JSON's simple values are the same as used in JavaScript • No restructuring is requested: JSON's structures are JavaScript! • JSON's object is the JavaScript object • JSON's array is the JavaScript array • Parsing is simple, native Ajax 101 30 30
  47. JSON Response: Parsing JSON Ajax XHR • Obtain responseText • Parse the responseText responseData = eval('(' + responseText + ')'); OR responseData = JSON.parseJSON(responseText); Ajax 101 31 31
  48. JSON Response:Y! JSON API Ajax XHR • http://api.search.yahoo.com/WebSearchService/V1/webSearch? appid=YahooDemo&query=finances&start=1&results=1&output=json { "ResultSet": { "totalResultsAvailable":"69200000", "totalResultsReturned":"1", "firstResultPosition":"1", "Result": { "Title":"Yahoo! Finance", "Summary":"manage the market and your money with Yahoo! Finance. Includes stock market quotes, business news, mutual funds, online bill pay, banking tools, loans, insurance, retirement planning, and tax tips and advice.", "Url":"http://finance.yahoo.com/", "ClickUrl":"http://finance.yahoo.com/", "ModificationDate":"1137225600", "MimeType":"text/html" } } } Ajax 101 32 32
  49. Getting info from a JSON response Ajax XHR http://api.search.yahoo.com/WebSearchService/V1/webSearch? appid=YahooDemo&query=finances&start=1&results=1&output=json Ajax 101 33 33
  50. Getting info from a JSON response Ajax XHR http://api.search.yahoo.com/WebSearchService/V1/webSearch? appid=YahooDemo&query=finances&start=1&results=1&output=json { "ResultSet": { "totalResultsAvailable":"69200000", "totalResultsReturned":"1", "firstResultPosition":"1", "Result": { "Title":"Yahoo! Finance", "Summary":"manage the market and your money with Yahoo! Finance. Includes stock market quotes, business news, mutual funds, online bill pay, banking tools, loans, insurance, retirement planning, and tax tips and advice.", "Url":"http://finance.yahoo.com/", "ClickUrl":"http://finance.yahoo.com/", "ModificationDate":"1137225600", "MimeType":"text/html" } } } Ajax 101 33 33
  51. Getting info from a JSON response Ajax XHR http://api.search.yahoo.com/WebSearchService/V1/webSearch? appid=YahooDemo&query=finances&start=1&results=1&output=json { "ResultSet": { "totalResultsAvailable":"69200000", "totalResultsReturned":"1", "firstResultPosition":"1", "Result": { "Title":"Yahoo! Finance", "Summary":"manage the market and your money with Yahoo! Finance. Includes stock market quotes, business news, mutual funds, online bill pay, banking tools, loans, insurance, retirement planning, and tax tips and advice.", "Url":"http://finance.yahoo.com/", "ClickUrl":"http://finance.yahoo.com/", "ModificationDate":"1137225600", "MimeType":"text/html" } } } responseData = JSON.parseJSON(responseText); var resultsAvail = responseData.ResultSet.totalResultsAvailable; var resultsReturned = responseData.ResultSet.totalResultsReturned; var firstResultTitle = responseData.ResultSet.Result.Title; var firstResultSummary = responseData.ResultSet.Result.Summary; Ajax 101 33 33
  52. Ajax JSON Trip Finder XHR Server XHR Ajax 101 34 34
  53. REST Service Request - Yahoo! Trip Planner - JSON Ajax XHR Yahoo! Trip Planner exposes its service via an URL that requires a free partner key. Notice output=json. http://api.travel.yahoo.com/TripService/V1/tripSearch? appid=PARTNER_KEY&query=alaska&output=json Server XHR Ajax 101 35 35
  54. JSON Response Ajax XHR {"ResultSet":{"firstResultPosition": 1,"totalResultsAvailable":"16","totalResultsReturned": 10,"Result":[ Each response is represented as an object in {"id":"351102","YahooID":"jk_95661","Title":"Cruise with a Y! service responds to Alaska from Vancouver","Summary":"Things to do: Whistler Blackcomb - an array (list) of Hiking,... Hotel: Hyatt Regency Vancouver, Howard JavaScript JSON text string, valid responses Jho...","Destinations":"Vancouver, Anchorage, This is passed object notation. Juneau, North directly back as the XHR Vancouver, Ketchikan, Se...","CreateDate":"1130437928","Duration":"16","Image": result {"Url":"http://us.i1.yimg.com/us.yimg.com/i/travel/tg/ lp/cd/ 100x100_cde24409e413d4d6da27953f6ab0bbde.jpg","Height":"100", "Width":"66"},"Geocode": {"Latitude":"49.284801","Longitude":"-123.120499","precision" :"not available"},"Url":"http://travel.yahoo.com/trip/? pid=351102&action=view"}, {"id":"400333","YahooID":"brdway_grl","Title":"Alaska","Summa ry":"Things to do: Moose's Tooth Pub and Pizzer... Restaurant: Orso, Simon's & Seafort's Salo...","Destinations":"Anchorage","CreateDate":"1134676973" ,"Duration":"10","Image":{"Url":"http://us.i1.yimg.com/ Server us.yimg.com/i/travel/tg/poi/ca/ 100x100_ca605c44b47e20a731d3093b94afa37e.jpg","Height":"75"," Width":"100"},"Geocode": XHR {"Latitude":"61.190361","Longitude":"-149.868484","precision" :"not available"},"Url":"http://travel.yahoo.com/trip/? pid=400333&action=view"}, ... Ajax 101 89 36 36
  55. The Ajax/JSON Code Ajax XHR <script> function showResponse() { if (xhr.readyState == 4) && (xhr.status == 200) { var helloArea = document.getElementById("helloArea"); var theTrip = eval( '(' + xhr.responseText + ')' ); var tripPlanHTML = ""; for(var i=0; i<theTrip.ResultSet.totalResultsReturned; i++) { var result = theTrip.ResultSet.Result[i]; tripPlanHTML = tripPlanHTML + '<div style="padding:4px;border:1px solid gray;width:'+ result.Image.Width+ ';"><img src="'+result.Image.Url+ '" width="'+result.Image.Width+ '" height="'+result.Image.Height+ '"></img></div>'+ '<div ><a href="'+result.Url+ '"><span style="font-weight:bold;font-size:18px;">'+ result.Title+'</span></a></div><div>'+ result.Summary+'</div><br/>'; } helloArea.innerHTML=tripPlanHTML; } else { alert('There was a problem with the request.'); } } </script> <h2>Find Trip Plans (using Ajax &amp; JSON)</h2> <p>Search for Trip Plans</p> <input id="searchCriteria" type="text"> <input value="Search" type="button" onclick="makeRequest('response_trip_planner_mult_json.jsp', document.getElementById('searchCriteria').value)"> <div style="height:300px;width:420px;margin-top:8px;padding:8px;" id="helloArea"></div> Ajax 101 37 37
  56. Ajax JSON Trip Finder XHR Server XHR Ajax 101 38 38
  57. Trigger. JavaScript Events Ajax 101 39 39
  58. JavaScript Trigger. JavaScript Events Events • Ajax interactions are kicked off by event & timer triggers • There are issues with event management within the browsers • You do need to understand these implications to write good Ajax applications Ajax 101 40 40
  59. JavaScript First, the Events Events onAbort onBlur onChange onClick onDblClick onDragDrop onError onFocus onKeyDown onKeyPress onKeyUp onLoad onMouseDown onMouseMove onMouseOut onMouseOver onMouseUp onMove onReset onResize onSelect onSubmit onUnload Ajax 101 41 41
  60. JavaScript Problem in a Nutshell Events • Different event models • Timing Issues • Confusing madness around the this pointer • Browser incompatibilities • Memory leak issues Ajax 101 42 42
  61. Different Ways to Assign Events JavaScript Events • Element Attributes • <element onclick=”func()” > • Element Properties (function reference) • element.onclick=func; • Event Binding Internet Explorer Mozilla (FF), Safari, Opera [W3C] attachEvent() addEventListener() detachEvent() removeEventListener() Ajax 101 43 43
  62. Confusing this Madness JavaScript Events • Element Attributes <a href=”#” onclick=”clickHandler(this)”> function clickHandler(anchorDOMElem) { // this == window --> window owns the function // anchorDOMElem was set to anchor DOM element this = anchorDOMElem; // fix this pointer } • Element Properties myAnchor.onclick=clickHandler; function clickHandler() { //this == anchorDOMElem --> anchorDOMElem owns the function } • Event Binding function AnchorLink(anchorDOMElem) { this.anchorDOMElem = anchorDOMElem; this.anchorDOMElem.onclick = this.clickHandler; this.anchorDOMElem.anchorLinkObj = this; } AnchorLink.prototype.clickHandler = function() { // this == anchorDOMElem or window, not AnchorLink object // confusing since this normally refers to AnchorLink // grab our normal this anchorLinkObj = this.anchorLinkObj; anchorLinkObj.doIt(); } AnchorLink.prototype.doIt = function() { // this == AnchorLink Object } Ajax 101 44 44
  63. Yahoo! UI Event Manager JavaScript Events • Standardizes event binding • Attach an event var helloAreaDiv = document.getElementById("hello-area"); function handleClick(e) { alert("click"); } YAHOO.util.Event.addListener(helloAreaDiv, "click", handleClick); • Attach multiple events var ids = ["el1", "el2", "el3"]; // array can contain object references, element ids, or both function handleClick(e) { alert(this.id); } YAHOO.util.Event.addListener(ids, "click", handleClick); • Handles automatic scope correction • By default “this” refers to the DOM element that the event was attached to • Can override scope Ajax 101 45 45
  64. YUI Scope Correction JavaScript openItem: function () { Events // schoolId is set out here var oThis = this; YAHOO.util.Event.addListener(markerFlag, 'click', function(e) { // this == markerFlag var schoolItem = oThis.schoolList.getItem(schoolId); schoolItem.open(); }/*noargs*/); } Ajax 101 46 46
  65. YUI Scope Correction JavaScript openItem: function () { Events Automatic // schoolId is set out here scope correction to target var oThis = this; YAHOO.util.Event.addListener(markerFlag, 'click', function(e) { element // this == markerFlag var schoolItem = oThis.schoolList.getItem(schoolId); schoolItem.open(); }/*noargs*/); } Ajax 101 46 46
  66. YUI Scope Correction JavaScript openItem: function () { Events // schoolId is set out here var oThis = this; YAHOO.util.Event.addListener(markerFlag, 'click', function(e) { // this == markerFlag var schoolItem = oThis.schoolList.getItem(schoolId); schoolItem.open(); }/*noargs*/); } openItem: function () { // schoolId is set out here YAHOO.util.Event.addListener(markerFlag, 'click', function(e, oThis) { // this == markerFlag var schoolItem = oThis.schoolList.getItem(schoolId); schoolItem.open(); }, this, false); } Ajax 101 46 46
  67. YUI Scope Correction JavaScript openItem: function () { Events // schoolId is set out here var oThis = this; YAHOO.util.Event.addListener(markerFlag, 'click', function(e) { // this == markerFlag var schoolItem = oThis.schoolList.getItem(schoolId); schoolItem.open(); }/*noargs*/); } openItem: function () { // schoolId is set out here YAHOO.util.Event.addListener(markerFlag, 'click', function(e, oThis) { // this == markerFlag var schoolItem = oThis.schoolList.getItem(schoolId); schoolItem.open(); }, this, false); } Pass in arbitrary object Ajax 101 46 46
  68. YUI Scope Correction JavaScript openItem: function () { Events // schoolId is set out here var oThis = this; YAHOO.util.Event.addListener(markerFlag, 'click', function(e) { // this == markerFlag var schoolItem = oThis.schoolList.getItem(schoolId); schoolItem.open(); }/*noargs*/); } openItem: function () { // schoolId is set out here YAHOO.util.Event.addListener(markerFlag, 'click', function(e, oThis) { // this == markerFlag var schoolItem = oThis.schoolList.getItem(schoolId); schoolItem.open(); }, this, false); } openItem: function () { // schoolId is set out here YAHOO.util.Event.addListener(markerFlag, 'click', function(e) { // this == Container Object var schoolItem = this.schoolList.getItem(schoolId); schoolItem.open(); }, this, true); } Ajax 101 46 46
  69. YUI Scope Correction JavaScript openItem: function () { Events // schoolId is set out here var oThis = this; YAHOO.util.Event.addListener(markerFlag, 'click', function(e) { // this == markerFlag var schoolItem = oThis.schoolList.getItem(schoolId); schoolItem.open(); }/*noargs*/); } openItem: function () { // schoolId is set out here YAHOO.util.Event.addListener(markerFlag, 'click', function(e, oThis) { // this == markerFlag var schoolItem = oThis.schoolList.getItem(schoolId); schoolItem.open(); }, this, false); } openItem: function () { // schoolId is set out here YAHOO.util.Event.addListener(markerFlag, 'click', function(e) { // this == Container Object var schoolItem = this.schoolList.getItem(schoolId); schoolItem.open(); }, this, true); } Override scope correction Ajax 101 46 46
  70. Other Issues JavaScript Events • Memory Leaks • IE’s garbage collection does simple reference counting • Attaching events and not removing them when finished will cause memory leaks • Can use an Observer style pattern to cache event handlers and at the end clean them up • Timing • Attempting to attach events before the page is loaded will cause problems • Do it on the onload Ajax 101 47 47
  71. Yahoo! UI Event Manager JavaScript Events • Automatic Listener Cleanup • Custom Events • getPageX, getPageY • onAvailable. Define a function to execute as soon as an element is detected in the DOM (during load) <script type="text/javascript"> function TestObj(id) { YAHOO.util.Event.onAvailable(id, this.handleOnAvailable, this); } TestObj.prototype.handleOnAvailable = function(me) { alert(this.id + " is available"); } var obj = new TestObj("myelementid"); </script> <div id="myelementid">my element</div> Ajax 101 48 48
  72. Update. The DOM Ajax 101 49 49
  73. DHTML Update. The DOM DOM • Browsers represent the user interface as a set of objects (or elements) • Since a page has a hierarchy of containment, each of these elements are related as parent-child or siblings • This takes the shape of a tree • The tree of elements is called the document object model or DOM. Specifically the Browser DOM. • Any change to the DOM structure or a DOM element is reflected immediately on the web page Ajax 101 50 50
  74. DHTML DOM DOM Example • Represented as a tree of nodes Ajax 101 51 51
  75. DHTML DOM Using the DOM • Think of JavaScript as the DOM manipulator • Use it to • Find DOM elements • Add new elements • Remove elements • Modify element attributes • Position elements • Style elements Ajax 101 52 52
  76. DHTML DOM Finding DOM Elements • document.getElementById • Prototype library shortcut: $(“idName”) or $(id) • Yahoo! library shortcuts: • YAHOO.util.Dom.get(“idName”) • getElementByClassName • parentNode • childNodes • Yahoo! library has ways to find ancestors Ajax 101 53 53
  77. DHTML DOM DOM Manipulation • Creating new interface elements • innerHTML, createElement(), createTextNode(), appendChild() • Changing element styles • Visual attributes • Geometry • Y!UI positioning, region detection • Y!UI classname & style normalization Ajax 101 54 54
  78. Example of DOM Manipulation (Hello World) DHTML DOM <h2>Ajax Hello World</h2> <p>Clicking the link below will use XHR to fetch the data and then show the result in the box below.</p> <span class="ajaxlink" onclick="makeRequest('response.jsp')"> Make an ajax request for data </span> <div id="helloArea"></div> 55 Ajax 101 55
  79. Example of DOM Manipulation (Hello World) DHTML DOM <h2>Ajax Hello World</h2> <p>Clicking the link below will use XHR to fetch the data and then show the result in the box below.</p> <span class="ajaxlink" onclick="makeRequest('response.jsp')"> Make an ajax request for data </span> <div id="helloArea"></div> 55 Ajax 101 55
  80. Example of DOM Manipulation (Hello World) DHTML DOM <h2>Ajax Hello World</h2> <p>Clicking the link below will use XHR to fetch the data and then show the result in the box below.</p> <span class="ajaxlink" onclick="makeRequest('response.jsp')"> Make an ajax request for data </span> <div id="helloArea"></div> var helloArea = document.getElementById("helloArea"); helloArea.innerHTML=rootNode.firstChild.data; 55 Ajax 101 55
  81. Example of DOM Manipulation (Hello World) DHTML DOM <h2>Ajax Hello World</h2> <p>Clicking the link below will use XHR to fetch the data and then show the result in the box below.</p> <span class="ajaxlink" onclick="makeRequest('response.jsp')"> Make an ajax request for data </span> <div id="helloArea"></div> var helloArea = document.getElementById("helloArea"); helloArea.innerHTML=rootNode.firstChild.data; 55 Ajax 101 55
  82. Advanced DOM Manipulation: Drag and Drop DHTML DOM ... <script type="text/javascript"> YAHOO.example.DDApp = function() { var dd; return { init: function() { var dd = new YAHOO.util.DD("dragDiv"); } } } (); YAHOO.util.Event.addListener(window, "load", YAHOO.example.DDApp.init); </script> <style type="text/css"> #dragDiv { background:url(images/macosxlogo.gif) 0 0 no-repeat; height:100px; width:70px; } </style> </head> <body> <h2>Drag and Drop</h2> <p>The Mac logo is draggable</p> <div id="dragDiv"></div> </body> ... Ajax 101 56 56
  83. Advanced DOM Manipulation: Animation DHTML DOM <html> <head> <style> #anim { background:#ccc;width:10px;height:20px;font-size:10%;} </style> <script type="text/javascript"> YAHOO.namespace('example.anim'); YAHOO.example.anim.init = function() { var myAnim = new YAHOO.util.Anim('anim', { width: {to: 200}, height: {to: 150}, fontSize: {from: 20, to: 120, unit: '%'}, opacity: {from: 0.25, to: 1.0 }}, 1, YAHOO.util.Easing.easeOut); var animate = function(e) { myAnim.animate(); return false; } YAHOO.util.Event.addListener(document, 'click', animate); } YAHOO.util.Event.addListener(window, 'load', YAHOO.example.anim.init); </script> </head> <body> <h1>Animation Example - Basic</h1> <p>This example demonstrates how to animate an element's width to a given value.</p> <p>Click anywhere to start animation.</p> <div id="anim">Lorem ipsum dolor</div> </body> Ajax 101 57 </html> 57
  84. DHTML DOM Keeping it Clean • Separate presentation style from content with CSS • Supports degradability • Supports accessibility • Simplifies maintenance • http://www.mezzoblue.com/css/cribsheet/ Ajax 101 58 58
  85. CSS DHTML DOM • Avoid these elements: • b, big, hr, i, small, sub, sup, tt • basefont, center, dir, font, isindex, menu, s, strike, u, tfoot • br is ok for content breaks; not layout • Make your HTML meaningful List structures as ul, li • Tree structures as nested ul, li • Containers as div • Use css selectors (contextual) • Reduces the number of classes • Avoid inline styles • Ajax 101 59 59
  86. Map Mashup Example • Using Maps API to populate a search result from local search Ajax 101 60 60
  87. Map Mashup Example • Using Maps API to populate a search result from local search Schools are shown on map based on geographical category search Ajax 101 60 60
  88. Maps Mashup Ajax 101 61 61
  89. Maps Mashup <div> <input id="searchInput" type="text"> <button id="searchButton" class="ygbt">Sear </div> Ajax 101 61 61
  90. Maps Mashup <div> <input id="searchInput" type="text"> <button id="searchButton" class="ygbt">Sear </div> <div class="gridCol4 map"> <div id="map-container"></div> </div> Ajax 101 61 61
  91. Maps Mashup <div> <input id="searchInput" type="text"> <button id="searchButton" class="ygbt">Sear </div> <div class="gridCol4 map"> <div id="map-container"></div> </div> schoolMap.ymap = new YMap(document.getElementById('map-container')); Map created, events set up schoolMap.ymap.drawZoomAndCenter(“94117”, schoolMap.zoomLevel); // map event captures to update map, search event YEvent.Capture(schoolMap.ymap, EventsList.changeZoom, schoolMap.updateMap); configured YEvent.Capture(schoolMap.ymap, EventsList.endPan, schoolMap.updateMap); YEvent.Capture(schoolMap.ymap, EventsList.endAutoPan, schoolMap.updateMap); YEvent.Capture(schoolMap.ymap, EventsList.endMapDraw, schoolMap.updateMap); schoolMap.ymap.disableKeyControls(); schoolMap.schoolList = new YAHOO.teacher_net.SchoolList('school-list'); YAHOO.util.Event.addListener("searchInput", 'keypress', schoolMap.searchWithEnterKey); YAHOO.util.Event.addListener("searchButton", 'click', schoolMap.searchLocation); Ajax 101 61 61
  92. Making Request for Local Search Via Connection Manager fetchSchools: function() { var centerLatLon = this.ymap.getCenterLatLon(); var unitsPerPixel = this.ymap.getUnitsPerPixel(); var outerRadius = this.ymap.getOuterRadius(); var latitude = centerLatLon.Lat; var longitude = centerLatLon.Lon; var radius = outerRadius * unitsPerPixel.miles; // Run through a simple php page proxy to get the data outside yahoo domain. var sUrl = "ajax/ajaxProxy.php?appid="+this.appid+ "&query="+this.query+ "&category="+this.category+ "&latitude="+latitude+ "&longitude="+longitude+ "&radius="+radius+ "&results="+this.results+ "&sort="+this.sort+ "&output=json"; // Start the ajax transaction. var request = YAHOO.util.Connect.asyncRequest('GET', sUrl, { success:this.buildMarkers, failure:this.handleFailure, scope:this }, null); }, Ajax 101 62 62
  93. Making Request for Local Search Via Connection Manager fetchSchools: function() { var centerLatLon = this.ymap.getCenterLatLon(); Called by var unitsPerPixel = this.ymap.getUnitsPerPixel(); Search, Update var outerRadius = this.ymap.getOuterRadius(); var latitude = centerLatLon.Lat; var longitude = centerLatLon.Lon; var radius = outerRadius * unitsPerPixel.miles; // Run through a simple php page proxy to get the data outside yahoo domain. var sUrl = "ajax/ajaxProxy.php?appid="+this.appid+ "&query="+this.query+ "&category="+this.category+ "&latitude="+latitude+ "&longitude="+longitude+ "&radius="+radius+ "&results="+this.results+ "&sort="+this.sort+ "&output=json"; // Start the ajax transaction. var request = YAHOO.util.Connect.asyncRequest('GET', sUrl, { success:this.buildMarkers, failure:this.handleFailure, scope:this }, null); }, Ajax 101 62 62
  94. Making Request for Local Search Via Connection Manager fetchSchools: function() { var centerLatLon = this.ymap.getCenterLatLon(); Called by var unitsPerPixel = this.ymap.getUnitsPerPixel(); Search, Update var outerRadius = this.ymap.getOuterRadius(); var latitude = centerLatLon.Lat; var longitude = centerLatLon.Lon; var radius = outerRadius * unitsPerPixel.miles; // Run through a simple php page proxy to get the data outside yahoo domain. var sUrl = "ajax/ajaxProxy.php?appid="+this.appid+ "&query="+this.query+ Create URL "&category="+this.category+ for local search API. "&latitude="+latitude+ Returns JSON. "&longitude="+longitude+ "&radius="+radius+ "&results="+this.results+ "&sort="+this.sort+ "&output=json"; // Start the ajax transaction. var request = YAHOO.util.Connect.asyncRequest('GET', sUrl, { success:this.buildMarkers, failure:this.handleFailure, scope:this }, null); }, Ajax 101 62 62
  95. Making Request for Local Search Via Connection Manager fetchSchools: function() { var centerLatLon = this.ymap.getCenterLatLon(); Called by var unitsPerPixel = this.ymap.getUnitsPerPixel(); Search, Update var outerRadius = this.ymap.getOuterRadius(); var latitude = centerLatLon.Lat; var longitude = centerLatLon.Lon; var radius = outerRadius * unitsPerPixel.miles; // Run through a simple php page proxy to get the data outside yahoo domain. var sUrl = "ajax/ajaxProxy.php?appid="+this.appid+ "&query="+this.query+ Create URL "&category="+this.category+ for local search API. "&latitude="+latitude+ Returns JSON. "&longitude="+longitude+ "&radius="+radius+ "&results="+this.results+ "&sort="+this.sort+ "&output=json"; // Start the ajax transaction. var request = YAHOO.util.Connect.asyncRequest('GET', sUrl, { success:this.buildMarkers, failure:this.handleFailure, Ajax call via YUI scope:this Connection Manager. Calls }, null); buildMarkers() }, Ajax 101 62 62
  96. JSON Returned {"ResultSet":{ "totalResultsAvailable":"207","totalResultsReturned":"20","firstResultPosition":"1","ResultSetMapUrl":"ht //local.yahoo.com/mapview?stx=school&radius=4.7591645003016&ed=06LvHa131DwCvYm93rvCDpEViPaxw2YYIc_1eQb "Result":[ {"id":"21358647","Title":"William De Avila Elementary School","Address":"1351 Haight St","City":"San Francisco","State":"CA","Phone":"(415) 241-6325","Latitude":"37.770162","Longitude":"-122.444543","Rating {"AverageRating":"1","TotalRatings":"1","TotalReviews":"0","LastReviewDate":"","LastReviewIntro":""},"Dis ce":"0.12","Url":"http://local.yahoo.com/details?id=21358647&stx=school&csz=San+Francisco +CA&ed=pcDSr6160SztFnD2q5vz7zFoy7Vvdme2t2cipDu09HUbifjdiG8NPxnRQKJe78oS0anj0Jgp","ClickUrl":"http:// local.yahoo.com/details?id=21358647&stx=school&csz=San+Francisco +CA&ed=pcDSr6160SztFnD2q5vz7zFoy7Vvdme2t2cipDu09HUbifjdiG8NPxnRQKJe78oS0anj0Jgp","MapUrl":"http:// maps.yahoo.com/maps_result?name=William+De+Avila+Elementary+School&desc=4152416325&csz=San+Francisco +CA&qty=9&cs=9&ed=pcDSr6160SztFnD2q5vz7zFoy7Vvdme2t2cipDu09HUbifjdiG8NPxnRQKJe78oS0anj0Jgp&gid1=21358647" usinessUrl":"http://sfusd.edu/","BusinessClickUrl":"http://sfusd.edu/","Categories":{"Category": [{"id":"96928445","content":"Elementary Schools"},{"id":"96928448","content":"High Schools"}, {"id":"96928449","content":"School Districts"}]}}, MORE RESULTS FOLLOW... Ajax 101 63 63
  97. JSON Returned {"ResultSet":{ "totalResultsAvailable":"207","totalResultsReturned":"20","firstResultPosition":"1","ResultSetMapUrl":"ht //local.yahoo.com/mapview?stx=school&radius=4.7591645003016&ed=06LvHa131DwCvYm93rvCDpEViPaxw2YYIc_1eQb "Result":[ {"id":"21358647","Title":"William De Avila Elementary School","Address":"1351 Haight St","City":"San Francisco","State":"CA","Phone":"(415) 241-6325","Latitude":"37.770162","Longitude":"-122.444543","Rating {"AverageRating":"1","TotalRatings":"1","TotalReviews":"0","LastReviewDate":"","LastReviewIntro":""},"Dis ce":"0.12","Url":"http://local.yahoo.com/details?id=21358647&stx=school&csz=San+Francisco +CA&ed=pcDSr6160SztFnD2q5vz7zFoy7Vvdme2t2cipDu09HUbifjdiG8NPxnRQKJe78oS0anj0Jgp","ClickUrl":"http:// local.yahoo.com/details?id=21358647&stx=school&csz=San+Francisco +CA&ed=pcDSr6160SztFnD2q5vz7zFoy7Vvdme2t2cipDu09HUbifjdiG8NPxnRQKJe78oS0anj0Jgp","MapUrl":"http:// maps.yahoo.com/maps_result?name=William+De+Avila+Elementary+School&desc=4152416325&csz=San+Francisco +CA&qty=9&cs=9&ed=pcDSr6160SztFnD2q5vz7zFoy7Vvdme2t2cipDu09HUbifjdiG8NPxnRQKJe78oS0anj0Jgp&gid1=21358647" usinessUrl":"http://sfusd.edu/","BusinessClickUrl":"http://sfusd.edu/","Categories":{"Category": [{"id":"96928445","content":"Elementary Schools"},{"id":"96928448","content":"High Schools"}, {"id":"96928449","content":"School Districts"}]}}, MORE RESULTS FOLLOW... Local Search Response in JSON Ajax 101 63 63
  98. Making Request for Local Search Via Connection Manager buildMarkers: function(o) { var JSONObject = eval('(' + o.responseText + ')'); var totalResults = JSONObject.ResultSet.totalResultsReturned; for (var i = 0; i < JSONObject.ResultSet.totalResultsReturned; i++) { var school = JSONObject.ResultSet.Result[i]; var markerLoc = new YGeoPoint(school.Latitude, school.Longitude); var myImage = new YImage(); myImage.src = 'http://us.i1.yimg.com/us.yimg.com/i/us/map/gr/map_mrkr_orng.gif'; myImage.size = new YSize(21,32); myImage.offsetSmartWindow = new YCoordPoint(0,0); var marker = new YMarker(markerLoc, myImage); marker.addLabel('<div style="padding-top:4px;">' + (i+1) + '</div>'); addopenMarkerWinListener(marker, school.id); this.ymap.addOverlay(marker); this.markerInfo[school.id] = {marker:marker, school:school}; addOpenMapItemListener(marker, school.id); } } Ajax 101 64 64
  99. Making Request for Local Search Via Connection Manager buildMarkers: function(o) { var JSONObject = eval('(' + o.responseText + ')'); var totalResults = JSONObject.ResultSet.totalResultsReturned; Convert for (var i = 0; i < JSONObject.ResultSet.totalResultsReturned; i++) { JSON response to var school = JSONObject.ResultSet.Result[i]; JavaScript object var markerLoc = new YGeoPoint(school.Latitude, school.Longitude); var myImage = new YImage(); myImage.src = 'http://us.i1.yimg.com/us.yimg.com/i/us/map/gr/map_mrkr_orng.gif'; myImage.size = new YSize(21,32); myImage.offsetSmartWindow = new YCoordPoint(0,0); var marker = new YMarker(markerLoc, myImage); marker.addLabel('<div style="padding-top:4px;">' + (i+1) + '</div>'); addopenMarkerWinListener(marker, school.id); this.ymap.addOverlay(marker); this.markerInfo[school.id] = {marker:marker, school:school}; addOpenMapItemListener(marker, school.id); } } Ajax 101 64 64
  100. Making Request for Local Search Via Connection Manager buildMarkers: function(o) { var JSONObject = eval('(' + o.responseText + ')'); var totalResults = JSONObject.ResultSet.totalResultsReturned; Convert for (var i = 0; i < JSONObject.ResultSet.totalResultsReturned; i++) { JSON response to var school = JSONObject.ResultSet.Result[i]; JavaScript object var markerLoc = new YGeoPoint(school.Latitude, school.Longitude); var myImage = new YImage(); myImage.src = 'http://us.i1.yimg.com/us.yimg.com/i/us/map/gr/map_mrkr_orng.gif'; myImage.size = new YSize(21,32); myImage.offsetSmartWindow = new YCoordPoint(0,0); var marker = new YMarker(markerLoc, myImage); marker.addLabel('<div style="padding-top:4px;">' + (i+1) + '</div>'); addopenMarkerWinListener(marker, school.id); this.ymap.addOverlay(marker); For each search result item, this.markerInfo[school.id] = {marker:marker, school:school}; create map markers, etc. addOpenMapItemListener(marker, school.id); } } Ajax 101 64 64
  101. Making Request for Local Search Via Connection Manager buildMarkers: function(o) { var JSONObject = eval('(' + o.responseText + ')'); var totalResults = JSONObject.ResultSet.totalResultsReturned; Convert for (var i = 0; i < JSONObject.ResultSet.totalResultsReturned; i++) { JSON response to var school = JSONObject.ResultSet.Result[i]; JavaScript object var markerLoc = new YGeoPoint(school.Latitude, school.Longitude); var myImage = new YImage(); myImage.src = 'http://us.i1.yimg.com/us.yimg.com/i/us/map/gr/map_mrkr_orng.gif'; myImage.size = new YSize(21,32); myImage.offsetSmartWindow = new YCoordPoint(0,0); var marker = new YMarker(markerLoc, myImage); marker.addLabel('<div style="padding-top:4px;">' + (i+1) + '</div>'); addopenMarkerWinListener(marker, school.id); this.ymap.addOverlay(marker); For each search result item, this.markerInfo[school.id] = {marker:marker, school:school}; create map markers, etc. addOpenMapItemListener(marker, school.id); } } Ajax 101 64 64
  102. Book Recommendation DHTML DOM • Jeremy Keith’s Dom Scripting • Definitive Guide JavaScript Fifth Edition • Mastering CSS Ajax 101 65 65

+ Bill ScottBill Scott, 3 years ago

custom

44856 views, 183 favs, 68 embeds more stats

Introduction to programming with Ajax. Covers XMLHt more

More info about this document

CC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike License

Go to text version

  • Total Views 44856
    • 40602 on SlideShare
    • 4254 from embeds
  • Comments 7
  • Favorites 183
  • Downloads 1
Most viewed embeds
  • 2073 views on http://woork.blogspot.com
  • 378 views on http://www.dreamcss.com
  • 375 views on http://www.getincss.ru
  • 278 views on http://www.adele.gouv.fr
  • 246 views on http://www.phpeye.com

more

All embeds
  • 2073 views on http://woork.blogspot.com
  • 378 views on http://www.dreamcss.com
  • 375 views on http://www.getincss.ru
  • 278 views on http://www.adele.gouv.fr
  • 246 views on http://www.phpeye.com
  • 208 views on http://abduzeedo.com
  • 208 views on http://dreamcss.blogspot.com
  • 184 views on http://podlipensky.com
  • 34 views on http://www.3wstudio.com.ar
  • 30 views on http://acidminds.com
  • 28 views on http://phpeye.com
  • 25 views on http://sc-net.blogspot.com
  • 24 views on http://www.nineteenlabs.com
  • 21 views on http://honeytech.wordpress.com
  • 20 views on http://www.webthreads.de
  • 16 views on http://innovationstartups.wordpress.com
  • 15 views on http://static.slideshare.net
  • 10 views on http://webthreads.de
  • 5 views on http://monw3c.blogbus.com
  • 4 views on http://allthingstechnology.blogspot.com
  • 4 views on http://feeds2.feedburner.com
  • 4 views on http://www.woork.blogspot.com
  • 4 views on http://localhost
  • 3 views on http://inmyfield.nsdesign2.net
  • 3 views on http://www.watchingtheweb.com
  • 2 views on http://www.infinitytricks.blogspot.com
  • 2 views on http://www.php404.cn
  • 2 views on http://www.einsoft.com.br
  • 2 views on http://209.85.129.132
  • 2 views on http://24per7.blogspot.com
  • 2 views on http://ajax101.blogspot.com
  • 2 views on http://localhost:3003
  • 2 views on http://lelya-s.blogspot.com
  • 2 views on http://www.webgox.com
  • 2 views on http://www.filescon.com
  • 2 views on http://egox.tumblr.com
  • 1 views on http://web-team.net.ua
  • 1 views on http://translate.googleusercontent.com
  • 1 views on http://en.av5.info
  • 1 views on http://rssnews.org.ua
  • 1 views on http://upbc-ajax.blogspot.com
  • 1 views on http://74.125.93.132
  • 1 views on http://eukproject.blogspot.com
  • 1 views on http://hghltd.yandex.net
  • 1 views on http://phpmysqlquestion.blogspot.com
  • 1 views on http://www.orachai.com
  • 1 views on http://www.danielwang.cn
  • 1 views on http://74.125.45.132
  • 1 views on http://www.hanrss.com
  • 1 views on http://static.slidesharecdn.com
  • 1 views on http://www.projectzero.org
  • 1 views on http://www.wait-till-i.com
  • 1 views on http://kesnebug.blogspot.com
  • 1 views on http://www.bee-box.com
  • 1 views on http://www.rapidshareabc.com
  • 1 views on http://reginagelfo.com
  • 1 views on http://www.blogger.com
  • 1 views on http://209.85.143.132
  • 1 views on http://74.125.79.132
  • 1 views on http://www.indianpad.com
  • 1 views on http://feedproxy.google.com
  • 1 views on http://xss.yandex.net
  • 1 views on http://www.newsgator.com
  • 1 views on http://74.125.77.132
  • 1 views on http://favit.bg
  • 1 views on http://feeds.feedburner.com
  • 1 views on http://e-blog-gr.blogspot.com
  • 1 views on http://localhost:3001

less

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

Cancel
File a copyright complaint
Having problems? Go to our helpdesk?

Categories