Slide 1

Slide 1 text

Entwicklung moderner Web-Apps mit HTML5 und JavaScript Thorsten Rinne / Sebastian Springer

Slide 2

Slide 2 text

Sebastian Springer Team Lead @ Mayflower

Slide 3

Slide 3 text

Thorsten Rinne Team Lead Engineering @ Yatego

Slide 4

Slide 4 text

Kontakt • Sebastian • sebastian.springer@mayflower.de • @basti_springer • Thorsten • [email protected] • @ThorstenRinne

Slide 5

Slide 5 text

Wer seid ihr?

Slide 6

Slide 6 text

• Browser • Yeoman = Bower + Grunt + Awesomeness • HTML5 und JavaScript APIs • Unsere Web App • Tipps & Tricks

Slide 7

Slide 7 text

Was braucht ihr?

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

Editor

Slide 10

Slide 10 text

Browser

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

Welche Versionen? • Chrome latest (derzeit Version 32) • Chromium latest (derzeit Version 34) • Firefox latest (derzeit Version 27) • Firefox Nightly latest (derzeit Version 30) • Safari latest (derzeit Version 6.1 bzw 7) • Opera kann man sich sparen, da wie Chrome

Slide 13

Slide 13 text

Fehlt da nicht jemand?

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

Welche IE Versionen?

Slide 16

Slide 16 text

• Internet Explorer 7 (??) • Internet Explorer 8 (?) • Internet Explorer 9 • Internet Explorer 10 (?) • Internet Explorer 11

Slide 17

Slide 17 text

Automatisierung

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

Entwickler sind faul.

Slide 20

Slide 20 text

• Linting • Abhängigkeiten auflösen • Zusammenfügen und Kompilieren • Testing • Debug Code entfernen

Slide 21

Slide 21 text

The JavaScript Task Runner $ npm install grunt-cli -g

Slide 22

Slide 22 text

The JavaScript Task Runner • aufgabenbasiertes Kommandozeilen-Tool • ähnlich make / rake / ant / phing • Konfiguration in JavaScript • Große Community • Hunderte Plugins • Linting, Concat, Watcher, Testing out of the box

Slide 23

Slide 23 text

Grunt installieren $ cd /path/to/project $ npm install grunt --save-dev

Slide 24

Slide 24 text

package.json { "name": „chat.js", "version": "1.0.0", "dependencies": {}, "devDependencies": { "grunt": "~0.4.1", "grunt-contrib-jshint": "~0.4.1", "grunt-contrib-uglify": "~0.2.2" }, "engines": { "node": ">=0.10.0" } }

Slide 25

Slide 25 text

Gruntfile.js module.exports = function(grunt) { ! grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), uglify: { options: { banner: '/*! <%= grunt.template.today("yyyy-mm-dd") %> */\n' }, build: { src: 'src/<%= pkg.name %>.js', dest: 'build/<%= pkg.name %>.min.js' } } }); ! grunt.loadNpmTasks('grunt-contrib-uglify'); ! grunt.registerTask('default', ['uglify']); ! };

Slide 26

Slide 26 text

Grunt Tasks // Run Jasmine and DalekJS tests grunt.registerTask(
 'testrun',
 ['jshint', 'jasmine', 'dalek'] ); ! // Build production grunt.registerTask(
 'production', ['copy', 'less', 'cssmin', 'jshint', 'uglify'] );

Slide 27

Slide 27 text

The JavaScript Task Runner • http://gruntjs.com • http://gruntjs.com/plugins

Slide 28

Slide 28 text

Linting • JSHint oder JSLint • .jshintrc $ npm install grunt-contrib-jshint --save-dev

Slide 29

Slide 29 text

LiveReload • Plugin • Chrome • Firefox • Safari • Triggert Seitenreload via grunt watch • Browser Extensions auf http://livereload.com/

Slide 30

Slide 30 text

Package Manager für das Web • Installieren und Entfernen von Paketen • Keine Abhängigkeiten • keine sudo Rechte nötig • Schnell installiert:
 
 $ npm install bower -g

Slide 31

Slide 31 text

Pakete installieren $ bower install $ bower install $ bower install # $ bower install =#

Slide 32

Slide 32 text

Paket-Quellen • Registrierte Bower-Pakete wie z.B. jQuery • Git-Repositories • Lokale Ordner • URLs mit .zip/.tar.gz Dateien • Werden normal nach bower_components installiert

Slide 33

Slide 33 text

Pakete suchen $ bower search angular Search results: ! angular git://github.com/angular/bower-angular.git angular-mocks git://github.com/angular/bower-angular-mocks.git angular-resource git://github.com/angular/bower-angular-resource.git angular-scenario git://github.com/angular/bower-angular-scenario.git angular-cookies git://github.com/angular/bower-angular-cookies.git angular-sanitize git://github.com/angular/bower-angular-sanitize.git angular-bootstrap git://github.com/angular-ui/bootstrap-bower.git

Slide 34

Slide 34 text

Pakete verwenden 


Slide 35

Slide 35 text

Pakete löschen $ bower remove $ bower remove jasmine

Slide 36

Slide 36 text

Konfiguration .bowerrc { "directory": "public/vendor" }

Slide 37

Slide 37 text

Konfiguration bower.json {
 "name": "yatego.com",
 "version": "2.0.0",
 "dependencies": {
 "jquery": "1.10.2",
 "bootstrap": "3.0.0",
 "modernizr": "2.6.2"
 },
 "devDependencies": {
 "jasmine": "~1.3.1", },
 "resolutions": {
 "jquery": "1.10.2"
 }
 }

Slide 38

Slide 38 text

Packen und Kompilieren • grunt-contrib-copy • grunt-contrib-concat • grunt-contrib-uglify • grunt-contrib-cssmin • grunt-contrib-imagemin

Slide 39

Slide 39 text

Schön. Und nun?

Slide 40

Slide 40 text

Geht das nicht noch einfacher?

Slide 41

Slide 41 text

Yeoman!

Slide 42

Slide 42 text

Yeoman • Scaffolding neuer Apps • Schreibt Grunt Konfiguration • Yeoman = Grunt + Bower + Awesomeness • über 500 Generatoren • Installation
 
 $ npm install -g yo


Slide 43

Slide 43 text

Yeoman $ npm install -g generator-webapp
 
 $ cd /path/to/webroot
 
 $ mkdir jsdays-app
 
 $ cd jsdays-app
 
 $ yo webapp


Slide 44

Slide 44 text

Yeoman und Grunt $ grunt server $ grunt test $ grunt build


Slide 45

Slide 45 text

Generator WebApp • Watcher für HTML, CSS und JS mit LiveReload • Builtin Webserver auf Port 9000 • JSHint • Mocha-Tests • Bootstrap 3

Slide 46

Slide 46 text

DEMO

Slide 47

Slide 47 text

Verfügbare Generatoren • AngularJS • Bootstrap • WordPress • EmberJS • Firefox OS Apps • ExpressJS • Laravel • Knockout • Jekyll • Phonegap • Meteor • Symfony2

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

Struktur • Frontend • JavaScript • LESS / CSS • Media • Tests • Backend • MVC • Templates • Routes • Tests

Slide 50

Slide 50 text


 Hallo, München

Hallo, München

Slide 51

Slide 51 text


 Hallo, München

Hallo, München

Slide 52

Slide 52 text


 Hallo, München

Hallo, München

Slide 53

Slide 53 text


 Hallo, München

Hallo, München

Slide 54

Slide 54 text


 Hallo, München

Hallo, München

Slide 55

Slide 55 text


 Hallo, München

Hallo, München

Slide 56

Slide 56 text


 Hallo, München

Hallo, München

Slide 57

Slide 57 text

Slide 58

Slide 58 text


 Hallo, München

Hallo, München

Slide 59

Slide 59 text

JavaScript API • FullScreen API • Forms • Webworkers • Geolocation • Storage • Offline Application

Slide 60

Slide 60 text

Full Screen

Slide 61

Slide 61 text

var elem = $('#content')[0]; if (elem.requestFullscreen) { elem.requestFullscreen(); } else if (elem.mozRequestFullScreen) { elem.mozRequestFullScreen(); } else if (elem.webkitRequestFullscreen) { elem.webkitRequestFullscreen(); } Full Screen

Slide 62

Slide 62 text

Full Screen if(document.cancelFullScreen) { document.cancelFullScreen(); } else if(document.mozCancelFullScreen) { document.mozCancelFullScreen(); } else if(document.webkitCancelFullScreen) { document.webkitCancelFullScreen(); }

Slide 63

Slide 63 text

• Bitte mit Vorsicht verwenden • Styling für z.B. Hintergrund: • -webkit-full-screen • -moz-full-screen Full Screen

Slide 64

Slide 64 text

Forms

Slide 65

Slide 65 text

Progress var interval = setInterval(function () { var progress = $('progress'); ! if (progress.val() < progress.attr('max')) { progress.val(progress.val() + 1); } else { clearInterval(interval); } }, 10);

Slide 66

Slide 66 text

Meter $('meter').val(100); Keine Progress-Bar! Zur Anzeige von Werten in einem bestimmten Wertebereich

Slide 67

Slide 67 text

Datalist ! Angela Merkel Gerhard Schröder ...

Slide 68

Slide 68 text

output $('#output').on('input', function () { var nr1 = parseInt($('#nr1').val()); var nr2 = parseInt($('#nr2').val()); $('output').val(nr1 + nr2); }); Element zur Ausgabe von Berechnungen

Slide 69

Slide 69 text

Slide 70

Slide 70 text

Input Types • Viele Aufgaben, die bisher mit JavaScript erledigt wurden, funktionieren jetzt mit HTML5 nativ • Können (kaum) angepasst werden

Slide 71

Slide 71 text

No content

Slide 72

Slide 72 text

Input types • tel • search • url • email • date • month • week • time • number • range • color

Slide 73

Slide 73 text

HINWEIS datetime und datetime-local sind deprecated!

Slide 74

Slide 74 text

No content

Slide 75

Slide 75 text

Attribute • autofocus • placeholder • form • required • autocomplete • pattern • dirname • novalidate • formaction • formenctype • formmethod • formnovalidate • formtarget

Slide 76

Slide 76 text

Webworker

Slide 77

Slide 77 text

Webworker • Workerthreads im Browser • Rechenintensive Prozesse auslagern • Zugriff auf: navigator, location, XMLHttpRequest,... • Kein Zugriff auf: DOM, window, document, parent

Slide 78

Slide 78 text

Webworker var worker = new Worker('/js/ webworker.js'); worker.onmessage = function (msg) { $('#result').html(msg.data); };

Slide 79

Slide 79 text

Webworker var i, n = 1, results = 1; outerLoop: while (true) { n += 1; for (i = 2; i <= Math.sqrt(n); i += 1) { if (n % i === 0) { continue outerLoop; } } self.postMessage(n); results += 1; if (results >= 1000) { self.close(); } }

Slide 80

Slide 80 text

No content

Slide 81

Slide 81 text

Websockets

Slide 82

Slide 82 text

Websockets • Bidirektionale Kommunikation zwischen Client und Server • Protokoll auf TCP-Basis • Eventbasiert • Sichere Variante wss://

Slide 83

Slide 83 text

Websockets var addr = 'ws://localhost:8181/'; var socket = new WebSocket(addr, 'myapp'); ! $('#sayHello').on('click', function () { socket.send('Hello Server'); }); ! socket.onmessage = function (msg) { $('#response').html(msg.data); }; !

Slide 84

Slide 84 text

var WebSocketServer = require('websocket').server; var http = require('http'); var server = http.createServer().listen(8181); wsServer = new WebSocketServer({ httpServer: server, autoAcceptConnections: false }); wsServer.on('request', function(req) { var connection = req.accept('myapp', req.origin); ! connection.on('message', function(message) { connection.sendUTF("Hello Client!"); console.log(message.utf8Data); }); });

Slide 85

Slide 85 text

Websockets

Slide 86

Slide 86 text

No content

Slide 87

Slide 87 text

Geolocation • Aktuelle Position des Clients • WLAN-Position • GPS-Position

Slide 88

Slide 88 text

Geolocation var geolocation = navigator.geolocation; ! geolocation.getCurrentPosition(function (pos) { var posString = 'Lat: ' + pos.coords.latitude + ' Long: ' + pos.coords.longitude; ! $('#position').html(posString); });

Slide 89

Slide 89 text

Geolocation

Slide 90

Slide 90 text

Geolocation

Slide 91

Slide 91 text

<script src="/js/geolocation2.js" /> <body> <div id="map-canvas"></div> </body> </html>

Slide 92

Slide 92 text

function initialize() { ! navigator.geolocation.getCurrentPosition(function (pos) { var myLatlng = new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude); var mapOptions = { zoom: 4, center: myLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP } var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions); ! var marker = new google.maps.Marker({ position: myLatlng, map: map, title: 'Hello World!' }); }); } ! google.maps.event.addDomListener(window, 'load', initialize);

Slide 93

Slide 93 text

Storage

Slide 94

Slide 94 text

Storage • Local Storage - zeitlich unbegrenzt • Session Storage - nur für eine Browser-Session • IndexedDB • Web SQL

Slide 95

Slide 95 text

Items in Storage:  
keyvalue
key:
value:
OK

Slide 96

Slide 96 text

var writeLine = function (k, v) { var line = '' + k + '' + v + 'delete' + ''; ! $('#content tbody').append(line); writeStorageLength(); }; ! ! for (var i = 0; i < localStorage.length; i++) { k = localStorage.key(i); v = localStorage.getItem(k); writeLine(k, v); }

Slide 97

Slide 97 text

var writeStorageLength = function () { $('#itemCount').html(localStorage.length); }; $('#save').on('click', function () { var k = $('#storageKey').val(); var v = $('#storageVal').val(); localStorage.setItem(k, v); writeLine(k, v); }); ! $('#content').on('click', function (e) { localStorage.removeItem((e.target). data('value')); $(e.target).closest('tr').remove(); writeStorageLength(); });

Slide 98

Slide 98 text

No content

Slide 99

Slide 99 text

Offline Application

Slide 100

Slide 100 text

Offline Application • Dateien werden nur einmalig vom Server geholt • Manifestdatei enthält die Konfiguration

Slide 101

Slide 101 text

Offline Application CACHE MANIFEST index.html ! js/articles.js js/customers.js js/init.js js/jquery.js js/orders.js ! css/bootstrap.css?v=1 ! NETWORK: orders offline.manifest

Slide 102

Slide 102 text

Offline Application

Slide 103

Slide 103 text

Creating Application Cache with manifest http:// localhost:8080/offline.manifest Application Cache Checking event Application Cache Downloading event Application Cache Progress event (0 of 7) http:// localhost:8080/js/customers.js Application Cache Progress event (1 of 7) http:// localhost:8080/css/bootstrap.css?v=1 Application Cache Progress event (2 of 7) http:// localhost:8080/js/jquery.js Application Cache Progress event (3 of 7) http:// localhost:8080/js/articles.js Application Cache Progress event (4 of 7) http:// localhost:8080/index.html Application Cache Progress event (5 of 7) http:// localhost:8080/js/init.js Application Cache Progress event (6 of 7) http:// localhost:8080/js/orders.js Application Cache Progress event (7 of 7) Application Cache Cached event

Slide 104

Slide 104 text

HTML5 Demos:
 github.com/thorsten/html5demos

Slide 105

Slide 105 text

No content

Slide 106

Slide 106 text

CSS LEVEL 3 • In der Entwicklung seit 2000 • Modularer Aufbau • Bekannte Module • Selectors Level 3 • Media Queries

Slide 107

Slide 107 text

Browser Prefixes • -moz- • -ms- / -mso- • -kthml- • -o- • -webkit- • n/a

Slide 108

Slide 108 text

Browser Prefixes .round-corners { border-radius: 12px; -moz-border-radius: 12px; -webkit-border-radius: 12px; -o-border-radius: 12px; -khtml-border-radius: 12px; }

Slide 109

Slide 109 text

Opacity Opacity Opacity Opacity

Slide 110

Slide 110 text

OPACITY .my-opacity { opacity: 0.8; -ms-filter: "alpha(opacity=80)"; filter:alpha(opacity=80); }

Slide 111

Slide 111 text

GRADIENTEN

Slide 112

Slide 112 text

Gradienten background: linear-gradient(135deg, #4c4c4c 0%,#595959 12%,#666666 25%,#474747 39%,#2c2c2c 50%,#000000 51%,#111111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%);

Slide 113

Slide 113 text

Anyone?

Slide 114

Slide 114 text

Gradienten filter: progid: DXImageTransform.Microsoft.gradient(
 startColorstr='#4c4c4c', endColorstr='#131313',
 GradientType=1
 );

Slide 115

Slide 115 text

Border Radius

Slide 116

Slide 116 text

Border Radius .curved { -moz-border-radius: 20px; -webkit-border-radius: 20px; -khtml-border-radius: 20px; border-radius: 20px; }

Slide 117

Slide 117 text

Box Shadow

Slide 118

Slide 118 text

Box Shadow .shadow { -webkit-box-shadow: 
 2px 2px 2px 2px rgba(0, 0, 0, 1); box-shadow: 
 2px 2px 2px 2px rgba(0, 0, 0, 1); }

Slide 119

Slide 119 text

Media Queries

Slide 120

Slide 120 text

Media Queries @media (min-width: 1200px) {
 ... } @media (min-width: 768px) and (max-width: 979px) { ... } @media (max-width: 767px) {
 ... } @media (max-width: 480px) {
 ... }

Slide 122

Slide 122 text

Selektoren Level 3 • p:nth-child(2n)
 Jedes 2.

Element seines Elternelements • :root
 Das Rootelement eines Dokuments • :empty
 Jedes Element ohne Kindelemente

Slide 123

Slide 123 text

Selektoren Level 3 • input:enabled
 Jedes aktive Element • input:disabled
 Jedes nicht aktive Element • input:checked
 Jedes „ge-checkte“ Element (Checkbox)

Slide 124

Slide 124 text

No content

Slide 125

Slide 125 text

Grundlagen und fortgeschrittene Themen • Modulloader • Frameworks • ECMAScript 5

Slide 126

Slide 126 text

Modulloader • Keine -Tags zum Laden • Abhängigkeiten auflösen • AMD Modules (Asynchronous Module Definition)

Slide 127

Slide 127 text

Modulloader • define: Wenn man ein Modul erstellen möchte, auf das weitere Module aufbauen • require: Wenn man Dinge laden und verwenden möchte

Slide 128

Slide 128 text

Modulloader define(
 “name”, 
 [deps...], 
 function (deps) {
 ...
 return x;
 });

Slide 129

Slide 129 text

Modulloader require(
 [deps...], 
 function (deps) {
 ...
 });

Slide 130

Slide 130 text

Frameworks

Slide 131

Slide 131 text

No content

Slide 132

Slide 132 text

ECMAScript 5

Slide 133

Slide 133 text

ECMAScript 5 • http://www.ecma-international.org/publications/files/ ECMA-ST/Ecma-262.pdf • JSON (parse, stringify) • Object.* • Strict Mode

Slide 134

Slide 134 text

JSLINT „JSLint will hurt your feelings“

Slide 135

Slide 135 text

JSLINT • „The JavaScript Quality Tool“ • http://www.jslint.com/ • Integriert in • CLI • IDE

Slide 136

Slide 136 text

“use strict”

Slide 137

Slide 137 text

Strict Mode - Mehr Fehler • Keine versehentlichen globals (ReferenceError) • Schärfere Regeln bei Zuweisungen • Non-writable, getter-only, neue Properties bei non-extensible Objekten • Kein Löschen von nicht löschbaren Eigenschaften (prototype) • Eindeutige Propertynamen • Eindeutige Namen für Argumente (function (a, a, b)...) • Keine Oktalnotation (z.B. 012 - SyntaxError)

Slide 138

Slide 138 text

Strict Mode Einfachere Benutzung • “with” ist verboten • (var x = 1; with (obj) { x};) • Keine neuen Variablen mit “eval” • eval(“var x”); • Keine Variablen löschen • var x = 123; delete x;

Slide 139

Slide 139 text

Strict Mode Eval & Arguments • eval und arguments können nicht mehr mit anderen Werten belegt oder an einen Kontext gebunden werden • arguments kann nicht mehr durch Aliases verändert werden • function func(arg) { var arg = 15; return [arg, arguments[0]]}; • arguments.callee existiert nicht mehr - TypeError

Slide 140

Slide 140 text

Strict Mode Sicherheit • Kein Zugriff mehr auf das globale Objekt aus Funktionen • function f() { return this; } - undefined • Kein Zugriff auf func.arguments und func.caller von außerhalb • Kein Zugriff auf Variablen in einer Funktion von außerhalb

Slide 141

Slide 141 text

Strict Mode • Reservierte Wörter: implements, interface, let, package, private, protected, public, static, und yield • Keine Funktionsdefinition in Bedingungen und Schleifen

Slide 142

Slide 142 text

Object.* • Erweiterbarkeit • Object.preventExtensions(obj) • Object.isExtensible(obj)

Slide 143

Slide 143 text

Object.* • Obj.create(proto, props) • Object.keys(obj) • Object.getOwnPropertyNames(obj) • Object.getOwnPropertyDescriptor(obj, prop) • Object.defineProperty(obj, prop, desc)

Slide 144

Slide 144 text

Object.* • Object.seal(obj)/Object.isSealed(obj) • Keine Änderungen mehr an Eigenschaften • Object.freeze(obj)/Object.isFrozen(obj) • Keine Schreibzugriffe mehr auf Eigenschaften + seal

Slide 145

Slide 145 text

Object.* • Object.defineProperty • set: magic setter function • get: magic getter function • value: default value • configurable: can be deleted • enumerable: can be iterated • writable: can be changed

Slide 146

Slide 146 text

No content

Slide 147

Slide 147 text

Chat

Slide 148

Slide 148 text

Realtime Chat • express.js • Handlebars Template Engine • Socket.IO • jQuery • Bootstrap 3

Slide 149

Slide 149 text

github.com/thorsten/chat-js

Slide 150

Slide 150 text

package.json { "name": "chat.js", "version": "1.0.0", "dependencies": { "express": "~3.4.8", "express-hbs": "~0.7.9", "socket.io": "~0.9.x" }, "repository": { "type": "git", "url": "git://github.com/thorsten/chat-js.git" } }

Slide 151

Slide 151 text

$ npm install $ bower install $ grunt

Slide 152

Slide 152 text

No content

Slide 153

Slide 153 text

socket.io var http = require('http'); var server = http.createServer(app); server.listen(8080); var io = require('socket.io').listen(server); ! io.sockets.on('connection', function (socket) { ! socket.on('msg', function(message) { console.log(message); }); ! });

Slide 154

Slide 154 text

script(src="http://localhost:3000/socket.io/ socket.io.js") var socket = io.connect('http://localhost:3000'); ! $('#chat').on('submit', function (e) { e.preventDefault(); var value = $('#message').val(); $('#message').val(''); $('#message').focus(); $('#messages').append(value + '
'); ! socket.emit('msg', value); return false; });

Slide 155

Slide 155 text

„App Insights“

Slide 156

Slide 156 text

No content

Slide 157

Slide 157 text

Bootstrap • Scaffolding (Grid, Layout, Responsive) • Base CSS (Buttons, Forms, Tables) • Components (Navigation, Alerts, Pagination) • JavaScript (Modal, Tooltip)

Slide 158

Slide 158 text

Bootstrap <link rel="stylesheet" type="text/css" href="/public/css/bootstrap.min.css">

Slide 159

Slide 159 text

Bootstrap

Slide 160

Slide 160 text

Dynamic Stylesheet Language

Slide 161

Slide 161 text

LESS • Variablen • Nested Rules • Mixins

Slide 162

Slide 162 text

LESS: Variablen @background: #FFFFE0; ! #messages { background-color: @background; }

Slide 163

Slide 163 text

LESS: Nested Rules #head { background-color: @dark; height:25px; div { color: @light; background-color: @dark; &:hover { background-color: @light; color: @dark; } } }

Slide 164

Slide 164 text

.rounded-corners (@radius: 10px;) { -webkit-border-radius: @radius; -moz-border-radius: @radius; border-radius: @radius; } ! #info { .rounded-corners(5px); width: 250px; margin: 10px; padding-left: 5px; background-color: lightgreen; } LESS - Mixins

Slide 165

Slide 165 text

Login

Slide 166

Slide 166 text

No content

Slide 167

Slide 167 text

Chat

Slide 168

Slide 168 text

No content

Slide 169

Slide 169 text

No content

Slide 170

Slide 170 text

CANVAS

Slide 171

Slide 171 text

No content

Slide 172

Slide 172 text

No content

Slide 173

Slide 173 text

No content

Slide 174

Slide 174 text

Little Helpers

Slide 175

Slide 175 text

Browser DevTools

Slide 176

Slide 176 text

chrome://flags Experimental Developer Tools experiments

Slide 177

Slide 177 text

Live editieren und speichern

Slide 178

Slide 178 text

Performance-Messung

Slide 179

Slide 179 text

Performance-Messung • Übersicht des Speicherverbrauchs • Hilft bei Suche nach Performanceproblemen • Layout oder Skripte • Ziel: 60 Frames pro Sekunde :-)

Slide 180

Slide 180 text

Memory und DOM Leaks

Slide 181

Slide 181 text

Memory und DOM Leaks • JavaScript CPU Profiling • Heap Snapshot für • JavaScript Objekte • DOM Knoten • Suche nach potentiellen Memory und DOM Leaks

Slide 182

Slide 182 text

Mobile Testing

Slide 183

Slide 183 text

Mobile Testing • User Agent • Verschiedene Endgeräte • Android • iOS • Windows Phone • Simulation von Touch Events • Ändern der Geolocation und des Accelerometers

Slide 184

Slide 184 text

No content

Slide 185

Slide 185 text

No content

Slide 186

Slide 186 text

POLYFILLS

Slide 187

Slide 187 text

POLYFILLS https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross- browser-Polyfills

Slide 188

Slide 188 text

No content

Slide 189

Slide 189 text

yepnope({ test : Modernizr.geolocation, yep : 'normal.js', nope : ['polyfill.js', 'wrapper.js'] });

Slide 190

Slide 190 text

Frameworks

Slide 191

Slide 191 text

Frameworks • Bootstrap • Ratchet v2 • Foundation v3 • Foundation v4 • Skeleton • 960.gs • http://responsive.vermilion.com/compare.php

Slide 192

Slide 192 text

No content

Slide 193

Slide 193 text

Mozilla Developer Network

Slide 194

Slide 194 text

No content

Slide 195

Slide 195 text

FRAGEN?

Slide 196

Slide 196 text

Kontakt Thorsten Rinne! [email protected] ! Yatego GmbH Kobellstr. 15 80336 München Deutschland ! @ThorstenRinne ! https://github.com/thorsten Sebastian Springer! sebastian.springer@mayflower.de ! Mayflower GmbH Mannhardtstr. 6 80538 München Deutschland ! @basti_springer ! https://github.com/sspringer82