- A shim lets you write the same code across all browsers by implementing a new API in downlevel browsers.
- A polyfill is a shim or collection of shims (and a catchy name).
- A prollyfill is a shim for a proposed API
- A helper helps write cross-browser code where a true API shim/polyfill is not possible.
Note that my general approach to polyfills is not to produce 100% compliant behavior, but to provide a broad subset of functionality so that, where possible, cooperative code can be written to take advantage of new APIs. No assumptions should be made about security or edge cases. It is preferrable to use a shim where it is possible to create one on supported browsers. If not possible, a helper should be used that lets the same code be used in all browsers.
I use these in various pages on my sites; most are by me, or I have at least tweaked them. A more comprehensive list can be found at The All-In-One Entirely-Not-Alphabetical No-Bullshit Guide to HTML5 Fallbacks by Paul Irish.
Bundled together; nearly every page I create needs at least some of these. These will change over time, and going forward I will only target IE8 and later.
XMLHttpRequest
(for IE6-)FormData
(for IE9-)- Selector API (for IE7-) - adapted from Paul Young
element = document.querySelector(selector)
elementArray = document.querySelectorAll(selector)
- DOM Events
- Where
EventTarget
iswindow
,document
, or any element: EventTarget.addEventListener(event, handler)
- for IE8+EventTarget.removeEventListener(event, handler)
- for IE8+window.addEvent(EventTarget, event, handler)
- helper for IE7- support - adapted from QuirksModewindow.removeEvent(EventTarget, event, handler)
- helper for IE7- support - adapted from QuirksModeEvent.target
Event.currentTarget
Event.eventPhase
Event.bubbles
Event.cancelable
Event.timeStamp
Event.defaultPrevented
Event.stopPropagation()
Event.cancelBubble()
- Where
- DOM Miscellany
document.head
elementArray = document.getElementsByClassName(classNames)
- HTML Web Application APIs (for IE9-)
encodedString = window.btoa(binaryString)
- Base64 EncodebinaryString = window.atob(encodedString)
- Base64 Decode
- HTML5 Infrastructure -
classList
spec,relList
spectokenList = elem.classList
- for IE8+tokenList = elem.relList
- for IE8+tokenList = window.getClassList(element)
- helper for IE7- supporttokenList = window.getRelList(element)
- helper for IE7- supporttokenList.length
tokenList.item(index)
tokenList.contains(token)
tokenList.add(token)
tokenList.remove(token)
tokenList.toggle(token)
- W3C Timing control for script-based animations - demo page
id = window.requestAnimationFrame()
window.cancelAnimationFrame(id)
- Efficient Script Yielding
id = setImmediate(callback, args...)
clearImmediate(id)
dataset
anddata-*
attributes spec (for IE8+, not available in IE7-)str = element.dataset[key]
- yields undefined if data-key attribute not presentelement.dataset[key] = str
- fails unless data-key attribute already present
- JavaScript 1.X String Extras
- String prototype:
trimLeft
,trimRight
,quote
- String prototype:
ECMAScript 5 Object, Function, String and Date extras:
- Object:
getPrototypeOf
,getOwnPropertyNames
,create
,defineProperty
,defineProperties
,keys
- Function prototype:
bind
- Array:
isArray
- Array prototype:
indexOf
,lastIndexOf
,every
,some
,forEach
,map
,filter
,reduce
,reduceRight
- String prototype:
trim
- Date:
now
- Date prototype:
toISOString
Does not include JSON - use json2.js
"Harmony" is the aspirational term for the future of ECMAScript (the standardized version of JavaScript) beyond ES5.
The standardization of ES6 is currently in progress. This will attempt to track the evolving spec, so may change at any time. This assumes ES5, so use es5.js for older browsers (IE9-).
In the ES6 Drafts:
- Object:
assign()
,is()
,setPrototypeOf()
- Symbol:
Symbol(description)
,Symbol.for()
,Symbol.keyFor()
,Symbol.iterator
,Symbol.toStringTag
- No security, just creates an object with a unique string representation.
typeof Symbol()
will incorrectly report"object"
butSymbol() instanceof Symbol
will returntrue
- No security, just creates an object with a unique string representation.
- Not supported:
Function.prototype.toMethod()
- Number:
EPILON
,isFinite()
,isInteger()
,isNaN()
,isSafeInteger()
,MAX_SAFE_INTEGER
,MIN_SAFE_INTEGER
,parseFloat()
,parseInt()
- Math:
acosh()
,asinh()
,atanh()
,cbrt()
,clz32()
,cosh()
,expm1()
,fround
,hypot()
,imul()
,log1p()
,log10()
,log2()
,sign()
,sinh()
,tanh()
,trunc()
- See also: uate - ES5 "Tagged Template Strings"
- String:
fromCodePoint()
,raw
- String prototype:
codePointAt()
,contains()
,endsWith()
,repeat()
,startsWith()
,[@@iterator]()
- Not supported:
String.prototype.normalize()
- see https://github.com/walling/unorm/
- Not supported:
- RegExp prototype:
replace()
,search()
,match()
- Array:
from()
,of()
- Array prototype:
copyWithin()
,entries()
,fill()
,find()
,findIndex()
,keys()
,values()
,[@@iterator]()
- TypedArray - for browsers without native support (IE9-) include typedarray.js
- %TypedArray% prototype:
from()
,of()
- %TypedArray% prototype:
copyWithin()
,entries()
,every()
,fill()
,filter()
,find()
,findIndex()
,forEach()
,indexOf()
,join()
,keys()
,lastIndexOf()
,map()
,reduce()
,reduceRight()
,reverse()
,slice()
,some()
,sort()
,values()
,[@@iterator]()
- Map:
clear()
,delete()
,entries()
,forEach()
,get()
,keys()
,has()
,set()
,size
,values()
,[@@iterator]()
- Set:
add()
,clear()
,delete()
,entries()
,forEach()
,has()
,size
,values()
,[@@iterator]()
- WeakMap:
clear()
,delete()
,get()
,has()
,set()
- WeakSet:
add()
,clear()
,delete()
,has()
- WeakMap and WeakSet are intrusive and modify the
valueOf
property of keys
- WeakMap and WeakSet are intrusive and modify the
- Promise:
p = new Promise()
,Promise.resolve()
,Promise.reject()
,Promise.cast()
,Promise.race()
,Promise.all()
,p.then()
,p.catch()
- promises spec
- Number:
compare()
- probably won't be in ES6 - Array prototype:
pushAll()
,contains()
ref - @dict module:
keys(dict)
,values(dict)
,entries(dict)
dict()
is shortcut forObject.create(null)
- this needs a rework
forOf(o, function(i) { ... })
- sincefor (i of o) { ... }
can't be polyfilled. Uses iterators, so works with arrays, maps, sets, and strings, via implicit @@iterator and explicit iterators returned by keys/values/entries methods and functions.
See also: uate - ES5 "tagged template strings"
script - unit tests - spec
Originally specified separately, Typed Arrays are now included in ES6.
ArrayBuffer
Uint8Array
,Int8Array
,Uint16Array
,Int16Array
,Uint32Array
,Int32Array
,Float32Array
,Float64Array
DataView
Creating index getter/setters (i.e. array[0]
, array[1]
, etc) is slow and consumes significant memory. Arrays larger than 100k entries will be too slow to initialize in most cases so an upper limit is placed on the size of arrays and exception is thrown on construction.
script - unit tests - draft spec - See script for cross-browser quirks
var url = new URL(url, base);
var value = url.searchParams.get(name);
var valueArray = url.searchParams.getAll(name);
url.searchParams.append(name, valueOrValues);
url.searchParams.delete(name);
URL objects have properties:
href
origin
protocol
username
password
host
hostname
port
pathname
search
searchParams
append(name, value)
delete(name)
get(name)
getAll(name)
has(name)
set(name, value)
hash
script - demo page - draft spec
// Adds the following properties to each KeyboardEvent:
event.code
event.location
// You can get a label for the key using:
KeyboardEvent.queryKeyCap(code);
// IE7- only: In your keydown/keyup handler, call this in your handler
// before accessing the `code` or `location` properties:
window.identifyKey(keyboardEvent);
script - demo page - spec - uses freegeoip.net
navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options);
var watchId = navigator.geolocation.watchPosition(successCallback, errorCallback, options);
navigator.geolocation.clearWatch(watchId);