Download presentation
Presentation is loading. Please wait.
Published byIrene Cross Modified over 9 years ago
1
Events & Callbacks (ESaaS §6.5) © 2013 Armando Fox & David Patterson, all rights reserved
2
Events What: occurrences that affect the user interface –User interacts with a page element –Previously-set timer expires –Data received from server in response to AJAX call (later) Events are usually (not always) associated with a DOM element Bind a handler (function) for a particular event type on one or more elements 2
3
Manipulating the DOM Using Events: Overview 1.Identify element(s) you will want to do stuff to, make sure they’re conveniently selectable using $() 2.Similarly, identify element(s) on which interactions will trigger stuff to happen 3.Write handler function(s) that cause the desired stuff to happen 4.In a setup function, bind the handlers (third way to call $() ) 3 2.5. Create failing test for handler using TDD http://pastebin.com/RSVXzgLR
4
Handlers on Buttons & Links A good summary of recognized handlers: http://www.chipchapin.com/WebTools/JavaScript/example1-04.html http://www.chipchapin.com/WebTools/JavaScript/example1-04.html What about links & buttons that are clickable without JavaScript? –handler runs first –if handler returns false, no other action taken –otherwise, other actions follow handler –example use: client-side form validation
5
Summary: jQuery & DOM Select elements with $() (or wrap to give them secret jQuery powers) Inspect them… text() or html() is(:checked), is(:selected), etc. attr('src') Add/remove CSS classes, hide/show Create setup function that binds handler(s) on element(s) – common ones: onclick, onsubmit, onchange –Pass func to $() (alias for document.ready() )
6
6 END
7
Browser will complain, but only when form’s Submit button clicked The form will be submitted, but without inputs being checked Nothing will happen when submit button is clicked (form won’t be submitted) Browser will complain about malformed HTML when page is loaded (server should respect browser version and not send JavaScript) ☐ ☐ ☐ ☐ 7 If this form is loaded in a non-JS-aware browser:
8
8 END
9
AJAX: Asynchronous JavaScript and XML (ESaaS §6.6) © 2013 Armando Fox & David Patterson, all rights reserved
10
AJAX == Asynchronous Javascript And XML JSAPI call XmlHttpRequest (a/k/a xhr ) contacts server asynchronously (in background) and without redrawing page –Normal HTTP request, w/special header: X-Requested-With: XmlHttpRequest Controller action receives request via route What should it render in response? render :layout => false render :partial => 'movies/show' render :json => @movies (calls to_json ) render :xml => @movies (calls to_xml ) render :text => @movie.title render :nothing => true
11
The Basic AJAX Cycle, As Seen From Browser JSAPI r = new XmlHttpRequest; r.open(method,URL,async); method GET,POST,HEAD,PUT,DELETE... async : true means script should not block (important!) r.send(" request content "); r.abort(); Callbacks during XHR processing r.onReadyStateChange=function(XmlHttpRequest r) {... } –function inspects r.readyState uninitialized,open, sent,receiving,loaded r.status contains HTTP status of response r.responseText contains response content string
12
The jQuery Way $.ajax({type: 'GET', url: URL, timeout: milliseconds, success: function, error: function // many other options possible });
13
Rails Cookery: AJAX with Rails+jQuery javascript_include_tag 'application' your code in app/assets/javascripts/*.js Define handler function that... –optionally inspects element state, attributes, … –calls $.ajax() Define controller action & route to receive request, and determine what will be returned Define callback function to receive server reply –Unpack JSON objects & modify DOM? –Replace existing HTML element (e.g. ) in place? –Add/change/remove CSS classes/properties?
14
A Simple Example Server side: class MoviesController < ApplicationController def show @movie = Movie.find(params[:id]) render :partial=>'movie', :object=>@movie if request.xhr? # else render default (show.html.haml) end Client side: 14 http://pastebin.com/zZPKvmVW
15
15 END
16
In general, the server must rely on explicit hints (like headers) to detect XHR The response to an AJAX request can be any content type (not just HMTL) If the server fails to respond to an XHR request, the browser’s UI will freeze AJAX requests can be handled with their own separate controller actions ☐ ☐ ☐ ☐ 16 Which is FALSE concerning AJAX/XHR vs. non-AJAX interactions?
17
17 END
18
Intro to Jasmine: TDD for JavaScript and AJAX (ESaaS §6.7) © 2013 Armando Fox & David Patterson, all rights reserved
19
Jasmine: Testing JavaScript Idea: run your tests in browser –Install jasmine gem & jasmine-jquery add-on –rails generate jasmine:install Jasmine “server” ( rake jasmine ) on localhost:8888 serves Jasmine test “page” –Reload page == rerun tests! How to construct tests? How do tests “see” the page on which they would normally operate? 19
20
Jasmine is Like RSpec Sets of related examples describe "things" do it "..." do...end end describe("things", function() { it("...", function() {... } ); }); Setup/teardown before(:each) do...end beforeEach(function() {...}) 20
21
Expectations expect {...}.to == "foo" expect( expr ).toEqual("foo").toBeTruthy(),.toBeFalsy().toBeHidden().toHaveClass().toContainText() 21
22
Expectations: Jasmine-jQuery toBeSelected(), toBeChecked() toBeDisabled(), toBeVisible(), toBeHidden() toHaveClass("foo"), toHaveId("foo") toHaveAttr("href", "http://saasbook.info") Putting it together example: describe('Clicking Hide button', function() { it('hides Movie div', function() { $('a#hide').trigger('click'); expect($('div#movie')).toBeHidden(); }); }); 22
23
23 END
24
(a) & (c) (b) & (c) (a), (b) & (c) (a) & (b) ☐ ☐ ☐ ☐ 24 Which are always true of Jasmine’s it() method: (a) it can take a named function as its 2 nd arg (b) it can take an anonymous function as its 2 nd arg (c) it executes asynchronously
25
25 END
26
More Jasmine: Spies & Fixtures (ESaaS §6.7) © 2013 Armando Fox & David Patterson, all rights reserved
27
Stubs (Spies) Strategy: create “spy” method that replaces real method that is a property of an object spyOn(MoviePopup,'new').andReturn(value).andCallThrough().andCallFake( func ) –Why no quotes around MoviePopup? Examine calls on spy: expect(MoviePopup.new.mostRecentCall.args). toContain("Gravity") expect($.ajax.mostRecentCall.args[0]['url']). toEqual("/movies/1") 27
28
HTML Fixtures Goal: provide enough HTML for JS code to do its thing in a familiar environment Casablanca PG More about Casablanca loadFixtures('movie_row.html') loads this into div#jasmine-fixtures (automatically cleaned out) Fallacies & Pitfalls for §6.7 shows how to auto- generate these fixtures from real views 28
29
Stubbing Redux 29
30
Putting it all together example Example Jasmine tests 30 http://pastebin.com/9xRk1CW1 http://pastebin.com/QNAuLLAt
31
31 END
32
$.ajax doesn't actually return the server reply content, so andReturn won't work ajaxArgs is in the wrong scope, so its value is not "visible" to andReturn We needed to be able to spy on (monitor) the AJAX call We could have done it either way; just a matter of choice ☐ ☐ ☐ ☐ 32 In the example, why did we use andCallFake() to pass ajaxArgs in stubbing the AJAX call, rather than just andReturn(ajaxArgs) ?
33
33 END
34
Single-Page Apps and JSON APIs (ESaaS §6.8) © 2013 Armando Fox & David Patterson, all rights reserved
35
Single-Page Apps Load page once; no further page reloads, since everything else done via AJAX Uses same MVC flows we already know! –but rendered content from server is handed to your JS code, not to browser So, what should controller method render? –Certainly not a full HTML page –HTML snippet? incorporate into page –“Raw” text? hard to send structured data –XML or JSON! 35
36
A Simple Example Server side: class MoviesController < ApplicationController def show @movie = Movie.find(params[:id]) render :json => @movie if request.xhr? # else render default (show.html.haml) end Client side: 36 http://pastebin.com/QNAuLLAt
37
37 END
38
In an association such as Movie has-many Reviews, the owned objects must be returned in 1 or more separate JSON objects JSON objects can only be consumed by a JavaScript-capable client None of the above are true A JSON object’s properties must exactly match the corresponding ActiveRecord model ☐ ☐ ☐ ☐ 38 Which, if any, of the following statements are TRUE regarding JSON objects in Rails apps?
39
39 END
40
And In Conclusion: JavaScript Wrapup (ESaaS §6.9-6.11) © 2012 Armando Fox & David Patterson Licensed under Creative Commons Attribution- NonCommercial-ShareAlike 3.0 Unported LicenseCreative Commons Attribution- NonCommercial-ShareAlike 3.0 Unported License
41
Emerging JS Use Cases Server-side frameworks: Node.js –JS library for creating server-side apps –Uses event-driven programming in JS –Potentially much more memory-efficient per user compared to traditional server-side frameworks –LinkedIn – Node.js 20x faster than Rails Client-side frameworks: Backbone.js –Express views & models entirely in JS –Server just returns JSON Client-side frameworks: Yahoo Mojito CoffeeScript http://pastebin.com/JJ9rEBDz
42
JavaScript & Performance The browser is increasingly the “client-side OS” that matters CSS has made layout increasingly sophisticated JavaScript + AJAX has made UI increasingly rich & desktop-like What’s the cost of all this?
43
Where Does the Time Go? CSS selectors + JavaScript interpreter = 41% of total client rendering time –Esp. selectors that require walking DOM tree, e.g. div > li Browsers compete on speed of JavaScript interpreter => selector/parser performance increasingly important Use GPU for rendering parser DOMCSS rules rendering 21% 23% 12% 29% 9% JavaScript interpreter layout engine HTML parser selector engine rendering JavaScript interpreter Courtesy Leo Meyerovich, UC Berkeley
44
Pitfall: “Adding JavaScript will make my app more responsive” Risk: too-wide API to server, with needlessly expensive database calls Risk: at mercy of JS interpreter on a wide variety of devices Risk: testing/debugging is more complicated, since must handle client-side errors
45
45 END
46
Slow database queries associated with AJAX actions Network delays due to sending too much data to browser in AJAX responses Can’t tell without further information Slow JavaScript interpreter (for example, users with very old browsers/computers) ☐ ☐ ☐ ☐ 46 Some of the AJAX interactions in Ben Bitdiddle’s AJAX-intensive SaaS app “feel sluggish”. The likeliest cause is:
47
47 END
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.