MOBILE WEB 5.0Michael Galpin, eBay
WHO AM I?
Michael Galpin
Mobile Architect, eBay
Android & Mobile Web
Author, Android in Practice
@michaelg
WHY?
Mobile is the new HOTness
MOBILEW E B THE IPHONE MYTH
MOBILEW E B
2 BIRDS, 1 STONE?
MOBILEW E B
ONE WEBKIT TO RULE THEM ALL?
MOBILEW E B
ONE WEBKIT TO RULE THEM ALL?
Android 2.2.1 iOS 4.1
MOBILEW E B
PARTY LIKE IT’S 2022
WHAT?
WHAT ABOUT?
OMG! VIDEO TAG!!!
HTML
HTML
JavaScript
CSS 3.0
MOBILEW E B
JUST ADD VIEWPORT?
HOW?
MOBILEW E B GEOLOCATION
geocoder = new google.maps.Geocoder();if (navigator.geolocation){ var gps = navigator.geolocation; gps.getCurrentPosition(function(pos){ var latLng = new google.maps.LatLng(pos.coords.latitude,pos.coords.longitude); var opts = {zoom:12, center:latLng, mapTypeId: google.maps.MapTypeId.ROADMAP}; map = new google.maps.Map($("map_canvas"), opts); theUser = new google.maps.Marker({ position: latLng, map: map, title: "You!" }); }); trackerId = gps.watchPosition(function(pos){ var latLng = new google.maps.LatLng(pos.coords.latitude,pos.coords.longitude); map.setCenter(latLng); theUser.setPosition(latLng); });}
MOBILEW E B GEOLOCATION
OS/Browser Status/Version
3.0
2.0
6.0
X
X
MOBILEW E B DOM STORAGE
if (window.localStorage){ localStorage.setItem("tweet" + tweet.id, JSON.stringify(tweet)); var index = localStorage.getItem("index::" + keyword); if (index){ index = JSON.parse(index); } else { index = []; } index.push(tweet.id); localStorage.setItem("index::"+keyword, JSON.stringify(index)); }
MOBILEW E B DOM STORAGE
if (window.localStorage){ localStorage.setItem("tweet" + tweet.id, JSON.stringify(tweet)); var index = localStorage.getItem("index::" + keyword); if (index){ index = JSON.parse(index); } else { index = []; } index.push(tweet.id); localStorage.setItem("index::"+keyword, JSON.stringify(index)); }
MOBILEW E B DOM STORAGE
OS/Browser Status/Version
3.0
2.0
6.0
7.0
X
MOBILEW E B WEB WORKERS
var worker = new Worker("details.js");worker.onmessage = function(message){ var responseXmlStr = message.data.responseXml; var itemDetails = parseFromXml(responseXmlStr); if (window.localStorage){ localStorage.setItem(itemDetails.id, responseXmlStr); } dealDetails[itemDetails.id] = itemDetails;};worker.postMessage(item.itemId);
onmessage = function(message){ var itemId = message.data; var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(){ if (this.readyState == 4 && this.status == 200){ postMessage({responseXml: this.responseText}); } }; var urlStr = generateUrl(itemId); xhr.open("GET", "proxy?url=" + escape(urlStr)); xhr.send(null);}
MOBILEW E B WEB WORKERS
OS/Browser Status/Version
X
2.0
6.0
X
X
MOBILEW E B WEBSOCKET
Data
if (window.WebSocket){ var conn = new WebSocket("ws://my.server.com/socket"); conn.onopen = function(){ setStatusMessage('connecting...'); conn.send('connect'); }; conn.onmessage = function(msg){ setStatusMessage('connected'); updateItemStatus(JSON.parse(msg.data)); }; conn.onerror = function(err){ showError(err); conn.close(); }; conn.onclose = function(evt){ setStatusMessage('connection closed'); };}
MOBILEW E B WEBSOCKET
OS/Browser Status/Version
4.2b
X
X
X
X
MOBILEW E B CANVAS
var ctx = $("graph").getContext("2d");ctx.font = "bold 12px sans-serif";ctx.textAlign = "start";for (i=0;i<data.length;i++){ ctx.fillStyle = "rgba(0, 0, 200, 0.9)"; ctx.fillRect(x, maxHeight - (data[i][report.y] / 2), width, (data[i][report.y] / 2)); ctx.fillStyle = "rgba(0, 0, 0, 0.9)"; ctx.fillText(data[i][report.x], x + (width / 4), maxHeight + 15); x += width + buffer;}ctx.moveTo(axisBuffer, maxHeight);ctx.lineTo(axisBuffer+maxWidth, maxHeight);ctx.strokeStyle = "black";ctx.stroke();ctx.moveTo(axisBuffer,0);ctx.lineTo(axisBuffer,maxHeight);ctx.stroke();
MOBILEW E B CANVAS
OS/Browser Status/Version
1.0
1.0
6.0
X
v2
MOBILEW E B CSS 3.0
$("formSection").style["-webkit-transform"] = "rotateZ(-5deg)";$("formSection").style["-webkit-transition"] = "-webkit-transform 2s ease-in-out";$("rtBtn").innerHTML = "Undo";$("rtBtn").onclick = function() { $("formSection").style["-webkit-transform"] = ""; $("rtBtn").innerHTML = "Rotate"; $("rtBtn").setAttribute("onclick", "rotate()");}
MORE CSS 3.0tr:nth-child(4n+1) { color: navy; }tr:nth-child(4n+2) { color: green; }tr:nth-child(4n+3) { color: maroon; }tr:nth-child(4n+4) { color: purple; }header > h1{ color: yellow; background: -webkit-gradient(linear, left top, left bottom, from(blue), to(white))}.xyz{ text-shadow: #6374AB 4px -4px 2px; overflow: hidden; text-overflow: ellipsis; border: 1px solid #bbb; border-radius: 9px; background-color: #fff;}
.abc { border: 1px solid #000; border-radius: 9px; -webkit-column-count:4; -webkit-column-rule: 1px solid #a00; -webkit-column-gap: 0.75em;}h2 { -webkit-text-fill-color: blue; -webkit-text-stroke-color: yellow; -webkit-text-stroke-width: 1.5px; background: -webkit-gradient(radial, 430 50, 0, 430 50, 200, from(red), to(#000)); -webkit-box-reflect:below 5px -webkit-gradient( linear, left top, left bottom, from(transparent), color-stop(0.5, transparent), to(white));}
MOBILEW E B CSS 3.0
OS/Browser Status/Version
3.0
2.0
X
X
X
MOBILEW E B
APPLICATION CACHE
<!DOCTYPE html><html manifest="manifest.mf"><head> <!-- ... --></head><body> <!-- ... --></body></html>
CACHE MANIFEST# Version 0.2CACHE:offline.htmljson2.js/images/gym.jpg/images/soccer.jpg/images/online.jpg
NETWORK:http://search.twitter.com/
MOBILEW E B APPLICATION
OS/Browser Status/Version
2.0
2.0
6.0
X
X
MOBILEW E B DEVICE
if (navigator.device.captureImage){ device.captureImage(function(data){ var file = data[0]; var xhr = new XMLHttpRequest(); xhr.upload.addEventListener("progress", function(e) { if (e.lengthComputable) { var percentage = Math.round((e.loaded * 100) / e.total); updateStatusBar(percentage); } }, false); xhr.open("POST", "http://my.server.com/upload"); xhr.overrideMimeType('text/plain; charset=x-user-defined-binary'); xhr.sendAsBinary(file.getAsBinary()); });}
MOBILEW E B DEVICE
OS/Browser Status/Version
X
3.0
X
X
X
MOBILEW E B TOUCH EVENTS
logo.ontouchmove = function(event){ if (event.touches.length == 1){ event.preventDefault(); var touch = event.touches[0]; var node = touch.target; node.style.position = "absolute"; node.style.left = touch.pageX + "px"; node.style.top = touch.pageY + "px"; }}
var angle = 0;logo.ongesturechange = function(event){ var node = event.target; node.style.webkitTransform = "rotate("+ ((angle + event.rotation) % 360)+"deg)";}logo.ongestureend = function(event){ angle = (angle + event.rotation) % 360;}
MOBILEW E B TOUCH EVENTS
OS/Browser Status/Version
2.0
1.0
6.0?
X
X
MOBILEW E B AUDIO/VIDEO
<video controls="controls" preload="true" width="720" height="640"> <source src="feature.ogg" type="video/ogg" /> <source src="feature.mp4" type="video/mp4" /> Your browser sucks</video>
MOBILEW E B AUDIO/VIDEO
OS/Browser Status/Version
1.0
2.0
X
X
X
MOBILEW E B META
<meta name="viewport" content="width=device-width; user-scalable=no;"/><meta name="apple-touch-fullscreen" content="YES" /><meta name="apple-mobile-web-app-capable" content="yes" /><meta name="apple-mobile-web-app-status-bar-style" content="black" /><link rel="apple-touch-icon" href="rice-and-bones.png"/>
NO REALLY, HOW?
MOBILEW E B
BEST PRACTICES
• Servers are for data
• Orientation matters
• Cache, cache, cache
• Frameworks (not really mobile): SproutCore, Cappuccino
• Frameworks (mobile): Sencha, jQTouch