building better experiences with responsive javascript (jonathan fielding)
DESCRIPTION
Taken from a talk at the London Web Meet-up - Building Better Experiences with Responsive Javascript "Responsive design has thus far focused on using media queries to alter the way our site looks using CSS. The next step is to look at how we can progressively enhance our site based on the the features of the device. This is going beyond what CSS can offer and moving into the realms of responsive javascript. There are already new browser API’s are arriving to enables this, with the matchMedia API we can target specific functionality based on whether a media query matches. Similarly we can add extra functionality and loads additional assets based upon features like geolocation and the camera. This is not building separate sites, its just changing the functionality of a single site based on the users device to optimise their experience. The aim of this talk is to help you learn about what you can do with responsive javascript. You will learn about how you can target specific functionality to different types of devices which enable you to optimise your user experience."TRANSCRIPT
Building Better Experiences with Responsive JavaScript
Jonathan Fielding @jonthanfielding
About me• Full stack developer • Been building responsively for
over 3 years • Worked with big brands like
Beamly, Virgin, Sony and BT
I asked some developers about what responsive design
meant to them
targeting different devices
@media screen and (max-width: 767px){
media queries
responsive grids
fluid layouts
These all focus on one thing
How the site looks
There is more to building a great responsive site than simply how it
looks
We also need to consider how the site functions
Why change functionality• Devices come in all shapes
and sizes • Input methods vary between
devices • Device functionality ranges
Examples
accordion on mobileopen content on desktop
single col on mobileequal columns on desktop
simple scrollable content on mobileparallax on desktop
new page on mobilelightbox on desktop
stacked content on mobile
swappable panels on desktop
What do these examples tell us
It’s ok to have different journeys for different devices on a responsive
site
Desktop journey
Mobile journey
Two ways to change functionality
• Based on viewport size • Based on the features the
device supports
xHow to change functionality based
on the viewport
Two key browser API’s• window.onresize • window.matchMedia
window.resize
Methodology• Add event to window.onresize • Use conditional statements to detect current
width of browser • Add debounce to resize event to
prevent it firing excessively
The code//debounce missing to keep example short
$(window).on('resize', function(){ if ($('body').width() < 768) { console.log('mobile'); } });
Could get messy• Lots of code simply placed in an
on resize event could potentially be messy
• Need to ensure there is a clear logical separation between different targeted viewport sizes
How to achieve the logical separation
if ($('body').width() < 768) { isMobile(); } !
if ($('body').width() >= 768) { isDesktop(); }
Browser Support
IEChromeFirefox Safari Android
window.matchMedia
Methodology• Prepare a MediaQueryList by using a
media query with window.matchMedia
• Add listener to MediaQueryList • When listener fires check if its a
match or unmatch
The codevar mql = window.matchMedia("(max-width:768px)"); mql.addListener(function(e){ if(e.matches){ console.log('enter mobile'); } });
Browser Support
IE 10+Chrome 9+Firefox 6+ Safari 5.1+ Android 3.0+
Real World Usage80.63%
of users have a browser that supports matchMedia
Libraries
Two popular libraries
SimpleStateManager (aka SSM)
What is SSM?• Responsive State Manager for JS • Uses Resize Event • Uses concept of states • Expandable with plugins
Setting up SSMTwo methods to setup SSM • Download from Github • bower install SimpleStateManager
The API• addState - Add Responsive
states • removeState - Remove
Responsive states • ready - tell SSM the states are
added and you are ready
Methodology• Prepare a state in the onEnter • Clean up a state in the
onLeave • Define a onResize event per
state (optional)
Adding a statessm.addState({ id: “mobile”, maxWidth: 767, onEnter: function(){ console.log(‘enter mobile’); } }).ready();
Removing a statessm.removeState('mobile');
Demo
Extending SSMSSM Plugins allow you to: • Extend the available state
options • Wrap jQuery Plugins to add
responsive functionality
Plugin Methodology• Add a custom config option • Use it like any other config option
in your states
Add a config optionssm.addConfigOption({name:"maxHeight", test: function(){ if(typeof this.state.maxHeight === "number" && this.state.maxHeight <= window.innerHeight){ return true; } else{ return false; } }});
Using the config optionssm.addState({ maxHeight: 480, onEnter: function(){ console.log(‘enter mobile’); } }).ready();
Summary• Create responsive states with
predefined rules of when it should be active
• Add onEnter, onLeave and onResize events to a state
• Use config options to add new tests
What is enquire.js• Awesome Media Queries in
JavaScript • Uses matchMedia API • Manages registering and
unregistering
Setting up enquire.jsTwo methods to setup enquire.js • Download from Github • bower install enquire
The API• register - registers a media
query attaching it to a handler • unregister - unregisters a media
query
Methodology• Register a media query with a
handler • Handler will fire when media
query matches • Unregister unneeded handlers
Registering a queryenquire.register("(max-width: 767px)", { match : function() { console.log("enter mobile"); }, });
Unregistering a queryenquire.unregister("(max-width: 767px)");
Demo
SummaryIn summary Enquire.js allows you to • Create listeners for media queries • Attach match and unmatch
methods to your listeners
SSM vs Enquire.jsSimpleStateManager Enquire.js
method onresize matchMedia
browser support IE7+, FF, O, C, S IE10+, FF, O, C, S
API events Enter, Leave, Resize Enter, Leave
Plugin Library yes no
In Summary• Looked at two API’s we can use
for responsive JavaScript • Looked at SimpleStateManager
and enquire.js as an option to simplify writing responsive JavaScript
xHow to change functionality based
device features
x
Methodology• Detect the features that a browser
supports • Progressively enhance your site
based on the features it supports
Using Modernizrif(Modernizr.geolocation){ console.log('Supports GeoLocation'); }
Use in conjunction with SSM• Create a SSM config option using
Modernizr for the test
Add a config optionssm.addConfigOption({name:"touch", test: function(){ if(typeof this.state.touch === "boolean" && this.state.touch === Modernizr.touch){ return true; } else{ return false; } }});
Using the config optionssm.addState({ touch: true, maxWidth: 767, onEnter: function(){ console.log(‘is mobile device that supports touch events’); } }).ready();
So how do we build better experiences using Responsive JavaScript?
By targeting functionality based on the characteristics of a device
Optimising the journey our user follows to best suit the device
Demo code from this talk at !
https://github.com/jonathan-fielding/ResponsiveJavaScriptTalkExamples
• Learn how to make your sites responsive
• Chapter on Responsive JavaScript • http://bitly.com/NXusZn • 35% off eBook discount code:
B3GW3B • 4 eBooks to give away today
Any Questions
Further ResourcesMDN - Testing Media Queries - mzl.la/18r5yGi
MDN – MediaQueryList - mzl.la/1bxbbZJ MDN – Window.matchMedia - mzl.la/19qc3Yk
SimpleStateManager – simplestatemanager.com Enquire.js - wicky.nillia.ms/enquire.js/
MatchMedia Polyfill - github.com/paulirish/matchMedia.js/ Jonathan Fielding’s Blog - jonathanfielding.com
!
Demo code from this talk at !
https://github.com/jonathan-fielding/ResponsiveJavaScriptTalkExamples