1 / 198

Building Accessible User Interfaces with JavaScript and jQuery

Building Accessible User Interfaces with JavaScript and jQuery. Antranig Basman, Core Framework Architect, The Fluid Project Clayton Lewis , Professor of Computer Science, University of Colorado at Boulder. Our Goals. Guide to the ropes and pitfalls of JavaScript jQuery

Download Presentation

Building Accessible User Interfaces with JavaScript and jQuery

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Building Accessible User Interfaceswith JavaScript and jQuery Antranig Basman, Core Framework Architect, The Fluid Project Clayton Lewis, Professor of Computer Science, University of Colorado at Boulder

  2. Our Goals • Guide to the ropes and pitfalls of • JavaScript • jQuery • A special emphasis on techniques appropriate for • Portals, Mashups and CMSs • Designing accessible, flexible apps • Finish by leading into the basics of Fluid Infusion

  3. Portals, Mashups, and CMSs • These days, diverse code and markup coexists • Most JavaScript is written as if it owns the whole browser • As you combine stuff, things can break • Namespacing and privacy is essential

  4. Schedule • Javascript 101 • 8:55 Break • jQuery • AJAX • Accessibility Basics • 9:55 Break • Accessibility Nuts and Bolts • 10:55 Break • Web 2.0 Accessibility and ARIA • Fluid Infusion • 11:55 Closing

  5. Modus Operandi • Brief introductions, so get to know one another a little • We’ll ask you to discuss with your neighbors from time to time • Questions, comments, and especially arguments are urged at any time!

  6. Javascript 101

  7. JavaScript is Different • Everything is an “object” • Extremely loose type system • - Only 6 types for values • - No types for references • No classes • Functions are first class • Some annoying quirks

  8. Super-Quick History • Netscape rushed JS to market, bugs and all, and with a shabbily motivated name • Microsoft reverse-engineered it. • Standards committee enforced the bugs. • In recent years JS has become a crucial technology • Big efforts on improved implementations have delivered huge performance gains

  9. Part 1: The Basics • Variables • null vs. undefined • Type coercion • Objects and Arrays

  10. Defining Variables • Define variables with var • Types are not specified • var mango = "yum"; • mango = 12345; • mango = false;

  11. Defining Variables • If you omit var, it will be defined as a global variable. • This is accident prone; JavaScript won't warn you! • rottenTomato = "gross!"; // This is global

  12. Numbers and Strings • Numbers • lots of precision • no distinction between floats and ints • NaN !== NaN • Strings • Unicode (mostly) • Immutable • No character type

  13. Null vs. Undefined • null is the "nothing" value • undefined is extremely nothing • Default value for uninitialized variables • Also the value of missing members of objects and arguments • exception thrown when the language encounters names which are not found in any scope • “typeof” expressions are safe and need to be used for detection here

  14. Truthy and Falsey • JavaScript does a lot of automatic type coercion • A common case is in conditions • Shades of true and false • Use with care if (x) x? thing1: thing2

  15. Falsey Values • false • null • undefined • "" • 0 (zero) • NaN • Everything else is truthy. Careful... • -1, "false", "0" are all true

  16. Equal vs. Equivalent • Comparisons are coercive: • 1 == "1" // true • 0 == false // true • Non-coercive comparison: • 0 === false // false • 1 !== "1" // true • 1 === Number("1") // true Don’t use this operator! Use this operator!

  17. Objects

  18. Objects Are Containers • At their core, objects are just maps or “dictionaries” • new Object() or {} returns an empty container of key/value pairs • Keys can be any string, values can be anything • Two different ways to access members: • basketOfFruit.kiwis; // dot notation • basketOfFruit["figs"]; // subscript notation • You can add new members to any object at any time Don’t use this! Use this! Use this!

  19. Objects Are Modifiable • var basketOfFruit = {}; • // New property • basketOfFruit.apples = "macintosh"; • // New method • basketOfFruit.eat = function () { • return “tasty”; • }

  20. No Classes • JavaScript doesn't have any concept of classes • Methods (functions) are just properties in a container: • pass them around • modify them • delete them

  21. Determining Types • JavaScript has a typeof keyword for determining type • var plum = "yum"; • if (typeof plum === "string") { • alert("Plum is a String!"); • }

  22. typeof is Inaccurate • // Inaccurate results for some built-in types • typeof({}) // 'object' • typeof([]) // 'object' • typeof(function() {}) // 'function' • typeof(“”) // 'string' • typeof(3) // 'number' • typeof(false) // 'boolean' • typeof(null) // 'object' • typeof(undefined) // 'undefined'

  23. Duck Typing • The best way to check for types: don’t. • Check for behaviour: • function countChickens (flock) { • if (flock.length && • typeof flock.length === “number”) { • //flock is ok to count. • } • } : fluid.isArrayable(eggs)

  24. Part 2: Functions & Scope • Functions are first class • Determining types • Understanding this • Closures

  25. First Class Functions • Functions are data (variable values) • You can assign them • You can pass them as arguments • You can return them as results • You can add members to a function(!) • convenient for managing names

  26. Defining and Using Functions • function squeeze(aFruit) { // familiarish… • … • } • var puree = function (aFruit) { // more generally useful • … • }; • function popsicle(juiceMakerFn, fruit) { • var juice = juiceMakerFn(fruit); • return freeze(juice); • } • var goody = popsicle(puree, berries); • var goody2 = popsicle(squeeze, berries);

  27. What Does This Mean? • No more anonymous inner classes! • You can pass bits of logic around and have them be invoked later • Callbacks are easy to write and ubiquitous • Functions are our basic building block

  28. this

  29. Context and this • JavaScript this pointer is wild and unpredictable • It points to different objects depending on the context • Subtle, confusing, and inexplicable

  30. The Reason For This, We Will Not Discuss • this is part of a package of language features (new, prototype, instanceof, constructor, this) which we (Fluid) do not recommend • We will present a simpler subset of the language that lets you get all your work done • Other dangerous features: eval, with • Ask us in the break or afterwards if you want to know more

  31. that

  32. Coping With the Problems • this can be confusing and unstable • Constructor functions can accidentally clobber the global namespace • Prototypal inheritance can easily cause existing code to break • Can we simplify things?

  33. Plain Old Functions & Objects • // Just use plain old functions and objects. • function orange () { • // Stable pointer to the current instance. • var that = {}; • // Anything private stays inside here. • // For public methods, just add properties. • that.squeeze = function () {...} • return that; • }

  34. Closures • Functions can be defined inside other functions • Inner functions have access to the outer function's variables • A closure is formed by returning the inner function from the outer function • The inner function will still have access to all the variables from the outer function

  35. A Simple Closure – Challenge #1 • function addNumbers (a, b) { • var sum = a + b; • function addEmUp (c) { • return sum + c; • } • return addEmUp; • } • var func = addNumbers(1, 2); • func(3); // Result is ??? • func(5); // Result is ???

  36. A Simple Closure • function addNumbers (a, b) { • var sum = a + b; • function addEmUp (c) { • return sum + c; • } • return addEmUp; • } • var add3 = addNumbers(1, 2); • // result is an “add 3” Function • add3(3); // Result is 6 • add3(5); // Result is 8

  37. Closures Simplify Event Handlers • function makeShowMessage(todaysPie) { • var messageToDisplay = “Today’s Pie is: ”; • return function(event) { • alert(messageToDisplay + " " + todaysPie); • showPictureOfPie(event.target, todaysPie); • } • } • var clickHandler = makeShowMessage(“Banana creme pie”); • $(element).click(clickHandler); //attach click handler using jQuery • // Shows an alert: "Today's pie is: Banana creme pie" • $(element).click(); //trigger event using jQuery

  38. Over to Antranig

  39. JavaScript Pitfall Challenge #2 • What is wrong with the following code? for (var i = 0; i < elements.length; i++) { var el = elements[i]; el.addEventListener('click', function() {      doSomethingWith(i, el); }); }

  40. “Creating functions in a loop” • A standard complaint from JSLint, a useful code quality tool • Sometimes this is OK • In this case it is not – the function body makes use of a variable held in the outer closure scope • Every listener will see i as n and el as undefined

  41. Basic Remedy #1 – extra function • An extra function needs to be created somehow to store fixed values in a scope • What a mess! for (var i = 0; i < elements.length; i++) { (function(i, el) { el.addEventListener('click', function() {      doSomethingWith(i, el); }); })(i, elements[i]); }

  42. Basic Remedy #2 – Use Framework support for iteration $.each(elements, function(i, el) { el.addEventListener('click', function() {      doSomethingWith(i, el); }); }); • Note that 2 functions are still needed OR fluid.each(elements, function(el, i) { el.addEventListener('click', function() {      doSomethingWith(i, el); }); });

  43. Advanced Remedy #3 – jQuery vectorisation • jQuery.click() is one of a large family of portable event binding methods provided by jQuery (mousemove, keydown, focus, etc.) • “A jQuery” wraps some collection of DOM elements • A jQuery be used to treat the wrapped collection homogeneously • Changes: • We don’t get to use the index “i” any more • Outer function level has disappeared, replaced by magic “this” $(elements).click(function(event) {      doSomethingWith(event.target); }; );

  44. Advanced Remedy #4 – jQuery.delegate() • Container is some DOM node containing the elements • “elementSelector” is some selector (from the CSS dialect) matching the elements • This is much more efficient, since it registers just ONE listener, no matter how many elements there are • event.target will differ from “this” which remains the container, but holds the element which received the event • Takes a bit more setting up, but is worthwhile in the long run $(container).delegate(“elementSelector”, “click”, function(event) {      doSomethingWith(event.target); }; });

  45. that

  46. Coping With Bugs • this can be confusing and unstable • Constructor functions can accidentally clobber the global namespace • Prototypal inheritance can easily cause existing code to break • Can we simplify things?

  47. Plain Old Functions & Objects • // Just use plain old functions and objects. • function orange () { • // Stable pointer to the current instance. • var that = {}; • // Anything private stays inside here. • // For public methods, just add properties. • that.squeeze = function () {...} • return that; • }

  48. Writing Collision-Free JavaScript • Put code in a unique namespace • Use closures for privacy • Support more than one on the page • Scope all variables to an instance • Avoid hard-baking ID selectors • Constrain selectors within a specific element These are policies followed by Fluid Infusion

  49. Keeping it to Ourselves • You should take namespacing seriously • Don’t steal global names • JavaScript globals • jQuery plugin names • HTML id values • others • Components are carefully scoped • Don’t expect control of the page

  50. Start With a Unique Namespace • // Add on to the fluid object if it exists, • // otherwise initialize it as an empty object. • var fluid = fluid || {};

More Related