Upgrade to Pro — share decks privately, control downloads, hide ads and more …

HTML5 Outliers

HTML5 Outliers

HTML5 isn't just video and canvas! There's a lot of clever related technology tucked away inside the mass of JavaScript specifications that aren't quite as sexy as a web socket making love to a canvas - but without a doubt, still useful and important to building web applications.This session will introduce you to some of those outliers, show you how they can be used and prepare you for making the most of what the browsers today can offer you.

Remy Sharp

June 06, 2012
Tweet

More Decks by Remy Sharp

Other Decks in Technology

Transcript

  1. ๏JavaScript in the browser ๏Browser came preinstalled ๏Also discovered WSH

    / .hta ๏Made apps: wallpaper changer http://www.flickr.com/photos/43805896@N00/3657783366/
  2. ๏Data storage ๏Real-time notifications ๏Desktop integration ๏Access to hardware ๏Local

    "install" ๏Go naked http://www.flickr.com/photos/21966325@N00/537474857/
  3. http://www.flickr.com/photos/redux/6188900810 "we have to stop advocating localStorage as a great

    opportunity for storing data as it performs badly" http://rem.io/link/182
  4. Valid email anyone? '@[10.10.10.10] user@[IPv6:2001:db8:1ff::a0b:dbd 0] "much.more\ unusual"@example.com "[email protected]"@exa mple.com

    "very.(),:;<>[]\".VERY.\"very@\\ \ \"very \".unusual"@strange.example.com 0@a !#$%&'*+-/=?^_`{}|[email protected] "()<>[]:;@,\\\"!#$%&'*+-/=? ^_`{}|\ \ \ \ \ ~\ \ \ \ \ \ \ ? \ \ \ \ \ \ \ \ \ \ \ \ ^_`{}| ~.a"@example.org ""@example.org postbox@com
  5. $('a[href^="/"]').click(function(e) { var target = e.currentTarget; if (!e.altKey && !e.ctrlKey

    && !e.metaKey && !e.shiftKey) { e.preventDefault(); url = target.pathname; navigate(url, { triggered: true }); } }); function navigate(url, data) { history.pushState(data, '', url); } window.onpopstate = function (event) { if (event.state.triggered) { ajaxLoad(location.pathname); } }
  6. $('a[href^="/"]').click(function(e) { var target = e.currentTarget; if (!e.altKey && !e.ctrlKey

    && !e.metaKey && !e.shiftKey) { e.preventDefault(); url = target.pathname; navigate(url, { triggered: true }); } }); function navigate(url, data) { history.pushState(data, '', url); } window.onpopstate = function (event) { if (event.state.triggered) { ajaxLoad(location.pathname); } } Select all internal links
  7. $('a[href^="/"]').click(function(e) { var target = e.currentTarget; if (!e.altKey && !e.ctrlKey

    && !e.metaKey && !e.shiftKey) { e.preventDefault(); url = target.pathname; navigate(url, { triggered: true }); } }); function navigate(url, data) { history.pushState(data, '', url); } window.onpopstate = function (event) { if (event.state.triggered) { ajaxLoad(location.pathname); } } If the user only clicked, ignore new tab clicks
  8. $('a[href^="/"]').click(function(e) { var target = e.currentTarget; if (!e.altKey && !e.ctrlKey

    && !e.metaKey && !e.shiftKey) { e.preventDefault(); url = target.pathname; navigate(url, { triggered: true }); } }); function navigate(url, data) { history.pushState(data, '', url); } window.onpopstate = function (event) { if (event.state.triggered) { ajaxLoad(location.pathname); } } Send the url path to our pushState function
  9. $('a[href^="/"]').click(function(e) { var target = e.currentTarget; if (!e.altKey && !e.ctrlKey

    && !e.metaKey && !e.shiftKey) { e.preventDefault(); url = target.pathname; navigate(url, { triggered: true }); } }); function navigate(url, data) { history.pushState(data, '', url); } window.onpopstate = function (event) { if (event.state.triggered) { ajaxLoad(location.pathname); } } Update window location and save the state data
  10. $(document).on('click', 'a[href^="/"]', function(e) { var target = e.currentTarget; if (!e.altKey

    && !e.ctrlKey && !e.metaKey && !e.shiftKey) { e.preventDefault(); url = target.pathname; navigate(url, { triggered: true }); } }); function navigate(url, data) { history.pushState(data, '', url); } window.onpopstate = function (event) { if (event.state.triggered) { ajaxLoad(location.pathname); } } Now when the user navigates to a url, or we manually push a new url (pushState), it fires popstate, and we ajaxLoad new content.
  11. EventSource ๏ Events emit from server ๏ Read only stream

    ๏ Simple API ๏ Possible to polyfill (so IE support)
  12. var es = new EventSource('/console'); es.onmessage = function (event) {

    var data = JSON.parse(event.data); execute(data.command); };
  13. var es = new EventSource('/console'); es.onmessage = function (event) {

    var data = JSON.parse(event.data); execute(data.command); }; // custom message type es.addEventListener('reload',function() { reloadData(); });
  14. "HTML5 drag and drop module is not just a disaster

    it’s a fucking disaster" http://rem.io/link/228 http://www.flickr.com/photos/redux/4640052438/
  15. var root = document.documentElement; root.addEventListener('dragover', cancel, false); root.addEventListener('dragend', cancel, false);

    root.addEventListener('drop', drop, false); function cancel(event) { event.preventDefault(); } function drop(event) { cancel(event); readFiles(event.dataTransfer.files); }
  16. var root = document.documentElement; root.addEventListener('dragover', cancel, false); root.addEventListener('dragend', cancel, false);

    root.addEventListener('drop', drop, false); function cancel(event) { event.preventDefault(); } function drop(event) { cancel(event); readFiles(event.dataTransfer.files); }
  17. var root = document.documentElement; root.addEventListener('dragover', cancel, false); root.addEventListener('dragend', cancel, false);

    root.addEventListener('drop', drop, false); function cancel(event) { event.preventDefault(); } function drop(event) { cancel(event); readFiles(event.dataTransfer.files); }
  18. var root = document.documentElement; root.addEventListener('dragover', cancel, false); root.addEventListener('dragend', cancel, false);

    root.addEventListener('drop', drop, false); function cancel(event) { event.preventDefault(); } function drop(event) { cancel(event); readFiles(event.dataTransfer.files); }
  19. function readFiles(files) { for (var i = 0; i <

    files.length; i++) { preview(files[i]); } } function preview(file) { var reader = new FileReader(); reader.onload = function (event) { var image = new Image(); image.src = event.target.result; holder.appendChild(image); }; reader.readAsDataURL(file); }
  20. function readFiles(files) { for (var i = 0; i <

    files.length; i++) { preview(files[i]); } } function preview(file) { var reader = new FileReader(); reader.onload = function (event) { var image = new Image(); image.src = event.target.result; holder.appendChild(image); }; reader.readAsDataURL(file); }
  21. function readFiles(files) { for (var i = 0; i <

    files.length; i++) { preview(files[i]); } } function preview(file) { var reader = new FileReader(); reader.onload = function (event) { var image = new Image(); image.src = event.target.result; holder.appendChild(image); }; reader.readAsDataURL(file); }
  22. var formData = new FormData(); for (var i = 0;

    i < files.length; i++) { formData.append('file', files[i]); }
  23. var formData = new FormData(); for (var i = 0;

    i < files.length; i++) { formData.append('file', files[i]); } // now post a new XHR request var xhr = new XMLHttpRequest(); xhr.open('POST', url);
  24. var formData = new FormData(); for (var i = 0;

    i < files.length; i++) { formData.append('file', files[i]); } // now post a new XHR request var xhr = new XMLHttpRequest(); xhr.open('POST', url); xhr.upload.onprogress = function (event) { if (event.lengthComputable) { var complete = (event.loaded / event.total ⏎ * 100 | 0); progress.value = complete; } }
  25. var formData = new FormData(); for (var i = 0;

    i < files.length; i++) { formData.append('file', files[i]); } // now post a new XHR request var xhr = new XMLHttpRequest(); xhr.open('POST', url); xhr.upload.onprogress = function (event) { if (event.lengthComputable) { var complete = (event.loaded / event.total ⏎ * 100 | 0); progress.value = complete; } } xhr.send(formData);
  26. <img class="boss-baddie" data-health="13" data-damage="5" src="..."> <script> var boss = document.getElementsByClassName('boss-baddie');

    if (gotHit) { me.health -= boss.dataset.damage; } else if (hitBaddie) { boss.dataset.health -= 1; if (boss.dataset.health === 0) { boss.classList.add('dead'); } } </script>
  27. <img class="boss-baddie" data-health="13" data-damage="5" src="..."> <script> var boss = document.getElementsByClassName('boss-baddie');

    if (gotHit) { me.health -= boss.dataset.damage; } else if (hitBaddie) { boss.dataset.health -= 1; if (boss.dataset.health === 0) { boss.classList.add('dead'); } } </script> element.dataset
  28. <img class="boss-baddie" data-health="13" data-damage="5" src="..."> <script> var boss = document.getElementsByClassName('boss-baddie');

    if (gotHit) { me.health -= boss.dataset.damage; } else if (hitBaddie) { boss.dataset.health -= 1; if (boss.dataset.health === 0) { boss.classList.add('dead'); } } </script> element.classList
  29. DO NOT UNDERESTIMATE USER EXPERIENCE. GOOD WEB SITES DO NOT

    AUTOMATICALLY MAKE GOOD APPLICATIONS.
  30. PARTING THOUGHTS 1. START USING TECHNOLOGY AVAILABLE TO YOU 2.

    VIABILITY COMES FROM MULTIPLE IMPLEMENTATIONS 3. DEMAND MORE ACCESS TO APIS 4. HTML5 = JAVASCRIPT