Estelle Weyl | @estellevw | Github | Press to advance, 2 for comments, 4 to read/write notes.

10 Things You Didn't Know
Browsers Could Do

Estelle Weyl

http://estelle.github.com/10

Hit "4" for notes

$('selector') without jQuery

Selectors API

Supported since IE8

Selectors API

var chil = $('#bar .foo');

Natively

var el   = document.querySelector('#bar');

var chil = el.querySelectorAll('.foo');

or

chil = document.querySelectorAll('#bar .foo');

Selectors API

Access DOM elements with standard CSS selectors.

document.querySelector(selector);
elem.querySelectorAll(selector);

Examples

document.querySelector('#id, li, #slides');
el.querySelectorAll('li:nth-of-type(odd)');

Spec: Selectors API level 1 | Selectors API Level 2

No Native Iteration

jQuery

$('#slides .slide').addClass('current');

Vanilla.js

var slides =
   d.querySelectorAll('#slides .slide');

for(var i=0; i < slides.length; i++){
   slides[i].classList.add('current');
}

Proof!

var slides = document.querySelectorAll('div.slide'),
  topics = document.querySelectorAll('h1.count'),
  summary = document.querySelector("#summary");

  summary.innerHTML = "There are " + slides.length +
  " slides covering " + topics.length +  " topics.";
Click me

static nodeList

RUN
QSA = d.querySelectorAll('#slides .slide')

if you increase # of slides, QSA.length doesn't change.

var QSA  = d.querySelectorAll('.slide');
var newSlide = d.createElement('div');
newSlide.classList.add('slide');
d.getElementById('slides').appendChild(newSlide);
console.log('Current QSA: ' + QSA.length);
Test Me

Everything can be editable

contentEditable

<body contenteditable>
  • Everything can be updated
  • Can even paste!
  • Updates the DOM
  • Turn anything into a form element
  • Supported since IE5

test me

Can store lots of data

LocalStorage

SessionStorage

WebSQL

IndexedDB

Your whole site with AppCache

Cookie Limitations

Cookies

  • Sent with every HTTP request (in plain text)
  • Limited to 4KB each, 20 per domain. 300 per browser.
  • No real API

Local and Session Storage

  • Not sent to server (more secure / less bandwidth)
  • Limited to 5MB each
  • Long term or session long
  • Simmple API

localStorage

save.addEventListener('click', function () {
  window.localStorage.setItem('key', textarea.value);
}, false);
textarea.value = window.localStorage.getItem('key');

Save text value on the client side (crash-safe)

// place content from local storage onLoad
var el = document.querySelector('#myID');
el.innerHTML = window.localStorage.getItem('key');

Slidedeck showNotes

// show/hide or create/activate notes on #4
addNotes: function(){
 var d = document;

 //if the textarea already exists, show it.
 if(d.querySelector('.current textarea.mynotes')) {
   d.querySelector('.current textarea.mynotes').classList.toggle('temphidden');
   return;
 }

 // if the text area doesn't exist, create it
 var ta = d.createElement('textarea'),
     currentSlide = d.querySelector('.current section'),
	   path = window.location.pathname,
     A = path.lastIndexOf('/') + 1,
     B = path.lastIndexOf('.'),
     firstPartOfKey,
     key;

 // create a unique key based on this page, deck & server
 if(B && B > A){
   firstPartOfKey = path.substring(A, B);
 } else {
   firstPartOfKey = path.substring(1, path.length-1) || 'home';
 }
 key = firstPartOfKey +  window.location.hash;

// if something was stored, show it
ta.value = window.localStorage.getItem(key) || '';
ta.className = 'mynotes';

 // save to localStorage on every keyup
 ta.addEventListener('keyup', function(){
    window.localStorage.setItem(key,ta.value);
 });

 //
 currentSlide.appendChild(ta);
},

Click in the code above before scrolling

Pause Game / User Name / High Scores

Play the Game

Data Storage

  • localStorage ➫ persistent storage
    Supported everywhere since ie8+
     
  • sessionStorage ➫ per tab storage
    Supported everywhere since ie8+
     
  • WebSQL ➫ Mobile Web Apps
    deprecated. Will never be in FF/IE
     
  • IndexedDB ➫ 2014?
    Found in IE10, FF, Chrome, BB. Not Safari or other mobile yet

Chrome: view storage: Inspector > Local Storage

SVG as Background Images

Latecomers: IE9 & Android 3

Animate your backgrounds on the fly!

  • Scalable Vector Graphics
  • 2D image format
  • supports interactivity and animation

SVG

.svgbg.current {
  background-image: url(star.svg), url(10.svg);
  background-size: 100px, auto;
  background-position: center, top;
}

Can count with CSS

Supported since IE8

Counters with Generated Content

#presentation {
  counter-reset: ten_features 0;
}
.count h1 {
  counter-increment: ten_features;
}
.count h1:before {
  content: counter(ten_features) ". ";
  background:
    url(star.svg) no-repeat -40px 2px / 250px 250px;
  padding: 15px;
}

CSS can Calculate

Prefixed in FF4, Saf6, BB10, Chr19, FF15 Android

Without prefix in FF16, IE 9+, Chrome 26

No Opera, Android or mobile Chrome love.... yet

CSS calc() function

calc()

width: calc(50% - 40px);
background: linear-gradient(
  black calc(50% - 2px),
  white calc(50% - 2px),
  white calc(50% + 2px),
  black calc(50% + 2px));

calc()

Try it out

calc()

Try it out

CSS Future Functions

min()

width: min(100px, 100%);
width: min(90px + 50px, 30%);

max()

width: max(100px, 100%);
width: max(90px + 50px, 30%)

toggle()

em {
  font-style: toggle(normal, italic);
}

IE6 and IE7 can buy you a house

Charge more for old IE browser support

Take your picture

Firefox, Chrome and Opera only

Take a picture

Action!

getUserMedia

if (navigator.getUserMedia) {
  navigator.getUserMedia({
    video: true,
    audio: true,
    toString : function() {
      return "video,audio";
    }
  }, onSuccess, onError);
} 

getUserMedia

navigator.getUserMedia =
    navigator.getUserMedia ||
    navigator.mozGetUserMedia ||
    navigator.webkitGetUserMedia ||
    navigator.msGetUserMedia);

Success CallBack

play = function(stream) {
  var source;
  if (window.webkitURL) {
    source = webkitURL.createObjectURL(stream);
  } else {
    source = stream; // Opera and Firefox
  }
  video.autoplay = true;
  video.src = source;
}

Click & Save

function takePhoto() {
  var context = photo.getContext('2d');
  context.drawImage(video, 0, 0, width, height);
}
function savePhoto() {
  var data = photo.toDataURL("image/png");
  data =
    data.replace("image/png","image/octet-stream");
  document.location.href = data;
}

Animate Sprites

animation-timing-function

simple animation

@keyframes W {
    0% {
      left: 0;
      top: 0;
    }
    25% {
      top: 400px;
    }
    50% {
      top: 50px;
    }
    75% {
      top: 400px;
    }
    100% {
      left: 80%;
      top: 0;
    }
}

animation-timing-function

#selector { 
  animation-name: nameYouMadeUp;
  animation-duration: 5s;
  animation-timing-function: ease-in-out;
}

possible values:

ease           linear
ease-in        ease-out
ease-in-out    cubic-bezier(x1, y1, x2, y2)
step-start /* same as steps(1, start) */
step-end /* same as steps(1, end) */
steps( X, start|end) /* X = # of steps + when change of value occurs */

Bezier Curves

cubic-bezier.com/

Sprite Animation

Try it out

Help you manage memory

In the debugger

Observer memory usage

In Chrome Developer Tools

Timeline tab ➫ memory

Thank you

@estellevw

http://estelle.github.com