Slide 1

Slide 1 text

F R O N T - E N D O F F U T U R E P A S T

Slide 2

Slide 2 text

#whoami ? My name is Nathan. I do UX and JS at TandemSeven. But most people know me as "the 960 guy" (that's ok). http:/ /sonspring.com | http:/ /960.gs | http:/ /tandemseven.com

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Download the slides and follow along: http:/ /j.mp/future-past Or, talk smack about me on Twitter: @nathansmith Note: You don't have to take notes feverishly.

Slide 5

Slide 5 text

* My predictive powers are average (at best). Today, I want to talk a bit about what the future of HTML, CSS, and JavaScript will look like.*

Slide 6

Slide 6 text

Difficult to see. Always in motion is the future.

Slide 7

Slide 7 text

To determine where we may be heading, let's reflect on where we've been…

Slide 8

Slide 8 text

PART 1: HOW WE GOT HERE

Slide 9

Slide 9 text

http:/ /w3.org/People/Raggett/book4/ch02.html HTML

Slide 10

Slide 10 text

http:/ /w3.org/People/Berners-Lee 1989: Tim Berners-Lee created HTML to link research docs.

Slide 11

Slide 11 text

"Storage of ASCII text, and display on [80x24] screens, is in the short term sufficient, and essential. Addition of graphics would be an optional extra with very much less penetration for the moment." – Tim Berners-Lee http:/ /w3.org/History/1989/proposal.html

Slide 12

Slide 12 text

http:/ /en.wikipedia.org/wiki/CERN HTML was for serious work. Initially, no tag.

Slide 13

Slide 13 text

Before long though, the masses got their hands it. That is when great chaos befell the Internet…

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

But, I digress. We're getting a little ahead of ourselves. ( sorry )

Slide 16

Slide 16 text

http:/ /en.wikipedia.org/wiki/Mosaic_(web_browser) Marc L. Andreessen Eric J. Bina

Slide 17

Slide 17 text

"Standardizing" on browser innovation… 1993: Marc Andreessen proposed the tag. Mosaic later becomes Netscape, which then introduces JS, SSL, etc.

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

JavaScript http:/ /oreilly.com/pub/a/javascript/2001/04/06/js_history.html

Slide 20

Slide 20 text

"JavaScript had to 'look like Java' only less so, be Java's dumb kid brother or boy- hostage sidekick. Plus, I had to be done in ten days or something worse than JS would have happened." Brendan Eich created JavaScript in 10 days. http:/ /en.wikipedia.org/wiki/Brendan_Eich

Slide 21

Slide 21 text

JavaScript is quirky and prototypal. Java is classy. Get it? :)

Slide 22

Slide 22 text

With classical inheritance, if your mother breaks her leg, you go visit her in the hospital. With prototypal inheritance, your leg would also (instantly) break. Object Inheritance #TLDR #TLDR = "Too Long, Didn't Read" aka: Sum it up for me :)

Slide 23

Slide 23 text

http:/ /en.wikipedia.org/wiki/Netscape_Navigator 1995: JavaScript debuted in Netscape Navigator 2.0.

Slide 24

Slide 24 text

The word "JavaScript" was chosen to tap into the brand name of the Java programming language. Sun Microsystems (since acquired by Oracle) owned the trademarks for both Java™ and JavaScript™, and stewards the development of Java (not JavaScript). In 1997, JavaScript (the language) was standardized by the European Computer Manufacturers Association, and it was dubbed "ECMAScript." http:/ /en.wikipedia.org/wiki/JavaScript | http:/ /en.wikipedia.org/wiki/ECMAScript Um - what? Brief history of JavaScript = Clear as mud...

Slide 25

Slide 25 text

Altogether different beasts: Both potentially delicious (or dangerous), but not actually derived from the same animal. Similar in name: JavaScript is to Java as Hamburger is to Ham.

Slide 26

Slide 26 text

With apologies to Jeremy Keith and Brad Colbow… http:/ /coding.smashingmagazine.com/2009/07/29/misunderstanding-markup-xhtml-2-comic-strip

Slide 27

Slide 27 text

1996: IE 3.0 ships with "JScript" (for copyright purposes). In 1995, MS begins to ship Internet Explorer with Windows 95. For Netscape, it was the beginning of the end. Microsoft also reverse- engineered JavaScript, as "JScript." http:/ /en.wikipedia.org/wiki/Internet_Explorer

Slide 28

Slide 28 text

Created at Netscape "ECMA TC39" Committee responsible for evolving the language Who is responsible for JavaScript now? {to name a few... http:/ /en.wikipedia.org/wiki/JavaScript | http:/ /en.wikipedia.org/wiki/ECMAScript TM of Oracle (via Sun)  Defines the ECMAScript DOM API

Slide 29

Slide 29 text

JS browser support is pretty good. JavaScript (ECMAScript 3.0) is supported fairly consistently in all major browsers. ⾨ This is Wikipedia's compatibility table* for: – Trident (IE) – Gecko (Firefox) – WebKit (Chrome & Safari) – Presto (Opera) * I realize those are rendering engines, not specific JS engines (which change names more rapidly). It's how Wikipedia lists 'em. http:/ /en.wikipedia.org/wiki/Comparison_of_layout_engines_(ECMAScript)

Slide 30

Slide 30 text

JavaScript is that friend in high school you secretly had a crush on, but was always hanging out with the sleazy boyfriend, DOM. Nice > What a punk! http:/ /w3.org/DOM

Slide 31

Slide 31 text

The Document Object Model (DOM) is what allows JS to interact with XML/HTML, ala: window.document.getElementsByTagName('*'); The DOM is stewarded by a different group than governs JS. Browsers also implement it slightly differently. For instance, IE historically didn't treat whitespace as text nodes, even though the official DOM spec says it should. http:/ /w3.org/DOM

Slide 32

Slide 32 text

2005: Then there was jQuery... Heck yeah! $('p.neat').addClass('ohmy').show('slow'); JavaScript that reads like CSS code!? http:/ /jquery.com

Slide 33

Slide 33 text

$(document).ready(function() { // Many tutorials put all the code here. }); But we treated it like CSS... Um, okay... What's the big deal?

Slide 34

Slide 34 text

Loosely translated: "You'd better lose yourself in the music, the moment. You own it, you better never let it go... You only get one shot, do not miss your chance to [load]." (with apologies to Eminem) window.onload http:/ /en.wikipedia.org/wiki/8_Mile_(film)

Slide 35

Slide 35 text

Really, it's not the fault of jQuery, nor of any other capable JavaScript libraries: Dojo, MooTools, Prototype, YUI, etc. As is almost always the case with code, the problem is actually a human one. We've become complacent and forgotten (or never learned) how JavaScript works. Beware the danger of abstraction & illiteracy. http:/ /ejohn.org/blog/javascript-language-abstractions

Slide 36

Slide 36 text

http:/ /w3.org/Style/LieBos2e/history/Overview.html CSS

Slide 37

Slide 37 text

http:/ /intercom.co.cr/www-archives/1994-q1/0648.html 1994: Marc Andreessen, on styling... "Sorry, you're screwed."

Slide 38

Slide 38 text

1994: Håkon Wium Lie proposed CSS. Initially it was called CHSS, ("Cascading HTML Style Sheets"), but was later shortened to simply CSS. 1996: The first browser to support CSS was Internet Explorer 3.0, followed closely by Netscape Navigator version 4.0. http:/ /people.opera.com/howcome/2006/phd

Slide 39

Slide 39 text

CHSS had 100 levels of !important h1.font.size = 24px 12% /* 12% importance */ h1.font.size = 16px 100% /* 100% importance */ h1.font.size = 12px 89% /* 89% importance */ h1 {font-size: 24px;} /* Applies globally (weak) */ h1.x {font-size: 16px;} /* More specific */ h1 {font-size: 12px;} /* Beats line 1, not line 2 */ Thankfully, CHSS was never implemented: CSS has "last-in" wins, with specificity override. http:/ /www.w3.org/People/howcome/p/cascade.html

Slide 40

Slide 40 text

Brief history of the first "Browser War" http:/ /en.wikipedia.org/wiki/Browser_wars

Slide 41

Slide 41 text

1998: "Web Standards" advocacy begins. http:/ /w3.org/Style/LieBos2e/history/Overview.html The box model isn't fixed until October 2006, in IE7 debut.

Slide 42

Slide 42 text

We made sites "best viewed in IE6," and Netscape lost the browser war. http:/ /en.wikipedia.org/wiki/Netscape_Navigator

Slide 43

Slide 43 text

The "dark side" = developing for 1 browser. Oh, what... Like you never photoshopped you vs. yourself with a lightsaber? C'mon! http:/ /flickr.com/photos/nathansmith/32757176

Slide 44

Slide 44 text

In 2001, IE had over 90% market share. https:/ /en.wikipedia.org/wiki/Browser_wars

Slide 45

Slide 45 text

2004: Firefox arose from Netscape's ashes. Thus began a new Browser War, still in progress.

Slide 46

Slide 46 text

Since then, IE has been in steady decline. http:/ /en.wikipedia.org/wiki/File:Usage_share_of_web_browsers_(Source_Net_Applications).svg

Slide 47

Slide 47 text

Chrome grew, at the expense of Firefox. http:/ /en.wikipedia.org/wiki/File:Usage_share_of_alternative_web_browsers_(Source_StatCounter).svg

Slide 48

Slide 48 text

Today, Chrome has overtaken IE… What!? https:/ /en.wikipedia.org/wiki/Browser_wars Chrome = green | IE = blue | Firefox = orange

Slide 49

Slide 49 text

"Those who cannot remember the past are condemned to repeat it." – George Santayana http:/ /en.wikipedia.org/wiki/George_Santayana So your "pure CSS" demo only works in WebKit?

Slide 50

Slide 50 text

PART 2: WHERE WE'RE GOING

Slide 51

Slide 51 text

http:/ /zeldman.com/2009/07/02/xhtml-wtf

Slide 52

Slide 52 text

Realistically speaking, XHTML 2.0 would've been a very tough sell, from a practical standpoint. It was extremely rigid. A page simply would not render, if it wasn't perfectly formed from an XML structural standpoint. Oh, and it would've done away with . Oh noes!

Slide 53

Slide 53 text

There were differing schools of thought on HTML vs. XHTML. In the field "make it work" Academic "make it valid"

Slide 54

Slide 54 text

rapid —> iteration http:/ /whatwg.org/specs/web-apps/current-work/multipage

Slide 55

Slide 55 text

Ian Hickson, benevolent HTML5 specification dictator curator… http:/ /en.wikipedia.org/wiki/Ian_Hickson

Slide 56

Slide 56 text

Technically, HTML5 is now a misnomer. (But, it's too late. Marketing already got ahold of it.) HTML is to be considered an ever-evolving "living standard." The WHATWG — Web Hypertext Application Technology Working Group — will continue to work on HTML, and the W3C will snapshot feature sets periodically, and tag them with incremental version numbers: HTML5 (and presumably, HTML6, etc). Thus, no more version numbers in DOCTYPE…

Slide 57

Slide 57 text

HTML5 "killed" XHTML. Good riddance, I say. <— Much easier to remember! As it turns out, is the minimum number of characters to trigger "standards" mode in older IE versions.

Slide 58

Slide 58 text

You don't have to type extra junk anymore. alert('This is some inline JS.'); /* <![CDATA[ */ alert('Are you kidding me?'); /* ]]> */

Slide 59

Slide 59 text

Have you ever used a non-CSS stylesheet? Note: Media queries are best defined via @media in a single stylesheet anyway, to avoid unnecessary HTTP requests. No? Me neither, so why "type" it?

Slide 60

Slide 60 text

You can't do that! What about the validator? Relax. It's valid. HTML5 is no longer a sub- set of SGML like all versions of HTML before it. Nor is it a spin on XML, like XHTML 1.x was. HTML is just HTML now. This is how browsers always treated (X)HTML anyway. I know what you XHTML purists are thinking: ( phew! ) http:/ /en.wikipedia.org/wiki/HTML

Slide 61

Slide 61 text

HTML5 CSS3 http:/ /w3.org/html/logo What about JS? It's actually not stewarded by the W3C.

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

https:/ /github.com/voodootikigod/logo.js

Slide 64

Slide 64 text

Branding, FTW! So, what's next? 1. Get cool logo(s). [X] 2. Convince others. [X] 3. Profit! [X]

Slide 65

Slide 65 text

http:/ /apple.com/html5 Apple likes HTML5.

Slide 66

Slide 66 text

http:/ /html5rocks.com Google likes HTML5.

Slide 67

Slide 67 text

https:/ /developer.mozilla.org/en/HTML/HTML5 Mozilla likes HTML5.

Slide 68

Slide 68 text

http:/ /opera.com/docs/specs/presto25/html5 Opera likes HTML5.

Slide 69

Slide 69 text

http:/ /msdn.microsoft.com/en-us/ie/aa740476 Microsoft likes HTML5.

Slide 70

Slide 70 text

HTML5 is gaining traction. http:/ /playbiolab.com

Slide 71

Slide 71 text

As of IE9, all browsers support . http:/ /ie.microsoft.com/testdrive/performance/asteroidbelt/default.html

Slide 72

Slide 72 text

2011: IE9 supports SVG (proposed in 1999). Examples of Dojo.js charts To be fair, IE renders SVG very fast, via hardware acceleration. Konqueror (WebKit predecessor), was the first browser to have built-in SVG support, in 2004. http:/ /user.sitepen.com/~dwalsh/dojo-charting.html

Slide 73

Slide 73 text

http:/ /flickr.com/photos/124330160/2127121118 And, each layer can respond to mouse events! SVG is like construction paper. Layers retain distinct shapes. SVG files work fine without JS.

Slide 74

Slide 74 text

http:/ /flickr.com/photos/azuriblue/3350954960 Canvas is like a whiteboard drawing, one layer. Note: Canvas only works in the browser via JS.

Slide 75

Slide 75 text

Quick CSS tip to fix IE's SVG rendering: svg { overflow: hidden; }

Slide 76

Slide 76 text

IE9, without the CSS fix for SVG: http:/ /host.sonspring.com/raph

Slide 77

Slide 77 text

IE9, with the CSS fix for SVG: http:/ /host.sonspring.com/raph

Slide 78

Slide 78 text

SVG in: Chrome, Firefox, Opera, & Safari. http:/ /host.sonspring.com/raph

Slide 79

Slide 79 text

I won't cover or in detail during this talk, but two helpful JavaScript libraries are worth noting... Raphaël (SVG) – Dmitry Baranovskiy Processing JS (Canvas) – John Resig http:/ /raphaeljs.com http:/ /processingjs.org

Slide 80

Slide 80 text

More Semantic Richness!
 New tags in HTML5 http:/ /html5doctor.com/element-index

Slide 81

Slide 81 text

etc...

etc... Mixes well with ARIA roles ( Accessible Rich Internet Applications )

Slide 82

Slide 82 text

The dawn of 3D browser graphics. aka: Can I play Farmville in IMAX!? WebGL is going to be HUGE ( eventually ) http:/ /en.wikipedia.org/wiki/WebGL

Slide 83

Slide 83 text

https:/ /github.com/mrdoob/three.js

Slide 84

Slide 84 text

https:/ /github.com/mrdoob/three.js

Slide 85

Slide 85 text

No content

Slide 86

Slide 86 text

No content

Slide 87

Slide 87 text

Thoughts on Metaprogramming… Haml => HTML Sass/Compass => CSS CoffeeScript => JS Note: Yes, I'm sure there are many, many more examples in the wild. But my time is finite, and this is what I'm familiar with. http:/ /haml-lang.com | http:/ /sass-lang.com | http:/ /compass-style.org | http:/ /coffeescript.org

Slide 88

Slide 88 text

Personal note: After giving 'em a try, I am on the fence regarding meta languages that treat whitespace as significant. Usual disclaimers apply: "It depends." Your mileage may vary. No purchase necessary. Machine-wash only. Enter at own risk. Batteries not included. Void where prohibited, etc.

Slide 89

Slide 89 text

Example of Sass (with Compass). @import compass/css3 // CSS3 helpers, etc. // I write this Sass code: .foobar +background-image(linear-gradient(#fff, #ccc)) +border-top-right-radius(4px) +box-shadow(rgba(#000, 0.5) 0 2px 5px 0) &:hover text-decoration: underline

Slide 90

Slide 90 text

Example of Sass (with Compass). /* This CSS is generated... */ .foobar { background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffffff), color-stop(100%, #cccccc)); background-image: -webkit-linear-gradient(#ffffff, #cccccc); background-image: -moz-linear-gradient(#ffffff, #cccccc); background-image: -o-linear-gradient(#ffffff, #cccccc); background-image: -ms-linear-gradient(#ffffff, #cccccc); background-image: linear-gradient(#ffffff, #cccccc); -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -o-border-top-right-radius: 4px; -ms-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-box-shadow: rgba(0, 0, 0, 0.5) 0 2px 5px 0; -webkit-box-shadow: rgba(0, 0, 0, 0.5) 0 2px 5px 0; -o-box-shadow: rgba(0, 0, 0, 0.5) 0 2px 5px 0; box-shadow: rgba(0, 0, 0, 0.5) 0 2px 5px 0; } .foobar:hover { text-decoration: underline; } BLOAT? Not really. You'd have to type all this to make it work cross-browser anyway.

Slide 91

Slide 91 text

Note: Don't indent unnecessarily with Sass. // This looks innocent enough: table.table-class tbody tr td a.link-class color: orange

Slide 92

Slide 92 text

Note: Don't indent unnecessarily with Sass. /* But it generates this... */ table.table-class tbody tr td a.link-class { color: orange; } /* When you probably just meant... */ .table-class .link-class { color: orange; }

Slide 93

Slide 93 text

Haml rocks, if you're in a Ruby project. To me, Haml means never typing this again...

Slide 94

Slide 94 text

Haml can generate nicely formatted HTML. I'm not an über-Ruby guy. Get your feet wet:

Slide 95

Slide 95 text

Okay, so abstraction for HTML and CSS is fine. It saves keystrokes, and those languages are pretty #yawn anyway, right? I mean, they're declarative, so of course we should automate them. But do not touch my JavaScript.

Slide 96

Slide 96 text

get.your(coffee) { return 'off my lawn'; }

Slide 97

Slide 97 text

Not everyone's a fan. Dustin Diaz, quoting Douglas Crockford:

Slide 98

Slide 98 text

http:/ /blog.meloncard.com/post/12175941935/how-one-missing-var-ruined-our-launch

Slide 99

Slide 99 text

http:/ /nodejs.org

Slide 100

Slide 100 text

Can you spot the bug? var joe = 1 sue = 2, bob = 3; var joe = 1, sue = 2, bob = 3; Bugs like this can be laborious to find, which is why I write...

Slide 101

Slide 101 text

It's okay to be obvious. var joe = 1; var sue = 2; var bob = 3; Minifiers like Uglify JS can handle removing repeated var keywords. Put that burden on automation, not yourself. https:/ /github.com/mishoo/UglifyJS | http:/ /marijnhaverbeke.nl/uglifyjs

Slide 102

Slide 102 text

Just tell JSLint… "Relax, it's okay." JSLint (and JSHint) is a great tool for checking for JS errors. But validation is a means to an end, not a goal in itself. If you want to ensure JSLint compliance, there's CoffeeScript... http:/ /jslint.com | http:/ /jshint.com

Slide 103

Slide 103 text

Recursion -> CoffeeScript is written in… CoffeeScript!? https:/ /plus.google.com/116264189418994838408/posts/CSXeyftovTJ

Slide 104

Slide 104 text

# CoffeeScript: $('#foobar').click -> # Do stuff. // JavaScript: $('#foobar').click(function() { // Do stuff. }); CoffeeScript -to- JavaScript... LOL - That's all? http:/ /coffeescript.org

Slide 105

Slide 105 text

# CoffeeScript: is_between = 1 < my_value < 10 // JavaScript: var is_between; is_between = (1 < my_value && my_value < 10); CoffeeScript = Syntactic Sugar... Oh, I see. http:/ /coffeescript.org

Slide 106

Slide 106 text

"Unless" is cool… # CoffeeScript: happy = true unless raining // JavaScript: var happy; if (!raining) { happy = true; } That's hawt. http:/ /coffeescript.org

Slide 107

Slide 107 text

Despite its positive aspects, I am not a fan of CoffeeScript. Why? Because it's more than just syntactic sugar. It's dangerous artificial sweetener, so to speak.

Slide 108

Slide 108 text

http:/ /coffeescript.org obj = foo: 'bar' for i in obj console.log obj[i] var i, obj, _i, _len; obj = { foo: 'bar' }; for (_i = 0, _len = obj.length; _i < _len; _i++) { i = obj[_i]; console.log(obj[i]); } Want to iterate through an object in CoffeeScript? Sure thing, just... WTF?

Slide 109

Slide 109 text

No content

Slide 110

Slide 110 text

http:/ /www.2ality.com/2013/06/iterators-generators.html let arr = ['foo', 'bar', 'baz']; for (let [index, element] of arr.entries()) { console.log(index + '. ' + element); } // Yields... // // 1. foo // 2. bar // 3. baz "for of" loops in the future…

Slide 111

Slide 111 text

http:/ /coffeescript.org obj = foo: 'bar' for i of obj console.log obj[i] var i, obj; obj = { foo: 'bar' }; for (i in obj) { console.log(obj[i]); } You would have to actually type this in CoffeeScript. Then the resulting JavaScript output is a "for in" loop.

Slide 112

Slide 112 text

This is why we can't have nice things!

Slide 113

Slide 113 text

Backbone.js — Actually pretty nice…

Slide 114

Slide 114 text

Underscore.js — Also nice…

Slide 115

Slide 115 text

But use Lo-Dash instead. It's more solid…

Slide 116

Slide 116 text

There are plenty of good MV* JS frameworks. &

Slide 117

Slide 117 text

No content

Slide 118

Slide 118 text

No content

Slide 119

Slide 119 text

No content

Slide 120

Slide 120 text

No content

Slide 121

Slide 121 text

Key tenets of most MV* JS frameworks: — Model, View, Controller (MVC) or… — Model, View, View Model (MVVM) — Two-way data binding… If user interacts with page, you can reflect these changes in your data — Declarative UI: in markup, not in JS — Observables: If data changes, UI updates

Slide 122

Slide 122 text

Trask-Industries.com (X-Men spoof site) uses Angular.js

Slide 123

Slide 123 text

Trask-Industries.com (X-Men spoof site) uses Angular.js

Slide 124

Slide 124 text

DEMO http://github.com/nathansmith/ko-table

Slide 125

Slide 125 text

No content

Slide 126

Slide 126 text

Below a certain width, the layout switches to a “mobile” view. The table rows & cells are display:block, and text from each is inserted as a label, preceding the data.

Slide 128

Slide 128 text

Slide 129

Slide 129 text

Slide 130

Slide 130 text

// In a real app, this data would potentially be dynamic. // But for the purposes of this demo, is hard-coded here. [ { "first_name": "Amy", "last_name": "Poehler", "character_first_name": "Leslie", "character_last_name": "Knope" }, { "first_name": "Nick", "last_name": "Offerman", "character_first_name": "Ron", "character_last_name": "Swanson" }, { "first_name": "Aziz", "last_name": "Ansari", "character_first_name": "Tom", "character_last_name": "Haverford" }, ... ]

Slide 131

Slide 131 text

// Extend KO array, to make it sortable ko.observableArray.fn.sort_by = function(key, reverse) { var self = this; self.sort(function(a, b) { var a_key = String(a[key]); var b_key = String(b[key]); var n, val; if (reverse) { n = a_key - b_key; val = !isNaN(n) ? n : b_key.localeCompare(a_key); } else { n = b_key - a_key; val = !isNaN(n) ? n : a_key.localeCompare(b_key); } return val; }); };

Slide 132

Slide 132 text

// APP.models models: { // APP.models.table_view_model table_view_model: function() { var self = this; // This data comes from "/json/data.js" APP.data = APP.data || ko.observableArray(DATA_JSON); self.data = APP.data; } }, ...

Slide 133

Slide 133 text

// APP.init.sort_by sort_by: function(key) { var event = 'click.sort_by'; var str = '.table-data th[data-key] a'; body.off(event).on(event, str, function(ev) { var el = $(this); var th = el.closest('th'); var th_other = th.siblings('th'); var key = th.attr('data-key'); var sort = th.attr('data-sort'); var asc = 'ascending'; var desc = 'descending'; var dir = asc; if (!sort || sort === asc) { dir = desc; } var reverse = dir !== asc; th.addClass(on).attr('data-sort', dir); th_other.removeClass(on).removeAttr('data-sort'); APP.data.sort_by(key, reverse); }); },

Slide 134

Slide 134 text

Get the slides… http:/ /j.mp/future-past Keep in touch… @nathansmith Questions? — I may (not) know the answer! http:/ /corsariomarcio.deviantart.com/art/X-MEN-DAYS-OF-FUTURE-PAST-poster-455872133