- 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.
My philosophy is that it's better to write future-looking code that takes advantage of new Web platform APIs where possible, and fill in the gaps with polyfills. There is no effort to produce 100% compliant behavior, or to completely hide differences in browser behavior.
I use these in various pages on my sites; most are by me, or I have at least tweaked them. A more comprehensive list of polyfills can be found at The All-In-One Entirely-Not-Alphabetical No-Bullshit Guide to HTML5 Fallbacks by Paul Irish.
You're already here! Great, just download it, or use:
git: git clone https://github.com/inexorabletash/polyfill.git
bower: bower install js-polyfills
npm: npm install js-polyfills
It is not packaged as Node.js module(s); there's nothing to
require()
, this is just for distribution.
Or just include scripts directly in your page via CDN (c/o RawGit):
<script src="https://cdn.rawgit.com/inexorabletash/polyfill/$TAGNAME/polyfill.min.js"></script>
(look at Releases for the tag name, e.g. "v1.2.3")
The polyfills are roughly split up into files matching 1:1 with Web standards (specifications, living standards documents, etc). So there is html.js for HTML, dom.js for DOM, etc.
Since I generally use several in my hobby projects, bundled/minified versions are available:
- web.js (minified: web.min.js) includes the most common Web polyfills - it assumes ES2015 support
- polyfill.js (minified: polyfill.min.js) has everything in web.js plus es5.js and es6.js
Minification is done via https://github.com/mishoo/UglifyJS2
ECMAScript 5 - Previous standard, supported by all modern browsers. Frozen.
ECMAScript 2015 - Most recent standard. Not fully supported by modern browsers yet.
ECMAScript proposed - Proposals for future editions of the standard. Here there be dragons.
JavaScript 1.X String Extras - ref
- String prototype:
trimLeft
,trimRight
,quote
script - tests - living standard
document.head
(for IE8-)- 'shiv' of newer HTML elements (
section
,aside
, etc), to fix parsing (for IE8-) 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
- Base64 utility methods (for IE9-)
encodedString = window.btoa(binaryString)
- Base64 EncodebinaryString = window.atob(encodedString)
- Base64 Decode
script - tests - living standard
- Selectors (for IE7-) - adapted from Paul Young
element = document.querySelector(selector)
elementArray = document.querySelectorAll(selector)
elem.matches(selector)
(for IE, Firefox 3.6, early Webkit and Opera 15.0)elementArray = document.getElementsByClassName(classNames)
(for IE8-)e = element.nextElementSibling
,e = element.previousElementSibling
(for IE8)- Node constants:
Node.ELEMENT_NODE
, etc (for IE8-) - DOMException constants:
DOMException.INDEX_SIZE_ERR
(for IE8-) - Events (for IE8)
- Where
EventTarget
iswindow
,document
, or any element:EventTarget.addEventListener(event, handler)
- for IE8+EventTarget.removeEventListener(event, handler)
- for IE8+
- Event:
target
,currentTarget
,eventPhase
,bubbles
,cancelable
,timeStamp
,defaultPrevented
,stopPropagation()
,cancelBubble()
- Where
- Non-standard Event helpers for IE7- - adapted from
QuirksMode
window.addEvent(EventTarget, event, handler)
window.removeEvent(EventTarget, event, handler)
- DOMTokenList -
classList
spec,relList
spec- DOMTokenList:
length
,item(index)
,contains(token)
,add(token)
,remove(token)
,toggle(token)
tokenList = elem.classList
- for IE8+tokenList = elem.relList
- for IE8+- Non-standard helpers for IE7-:
tokenList = window.getClassList(element)
tokenList = window.getRelList(element)
- DOMTokenList:
- ParentNode:
node.prepend(nodes...)
,node.append(nodes...)
- ChildNode:
node.before(nodes...)
,node.after(nodes...)
,node.replaceWith(nodes...)
,node.remove()
script - tests - living standard
Example:
fetch('http://example.com/foo.json')
.then(function(response) { return response.json(); })
.then(function(data) { console.log(data); });
Supported:
- Headers:
new Headers()
,append(name, value)
,delete(name)
,get(name)
,getAll(name)
,has(name)
,set(name, value)
,[Symbol.iterator]()
- Body:
arrayBuffer()
,blob()
,formData()
,json()
,text()
- but conversions are limited - Request:
new Request(input, init)
,method
,headers
,body
,url
- Response:
new Response(body, init)
,headers
,url
,status
,statusText
,body
fetch(input, init)
script - tests - living standard
XMLHttpRequest
(for IE6-)FormData
(for IE9-)
- W3C Timing control for script-based animations - demo page
id = window.requestAnimationFrame()
window.cancelAnimationFrame(id)
- Efficient Script Yielding
id = setImmediate(callback, args...)
clearImmediate(id)
Polyfill for width
and height
in getBoundingClientRect()
in IE8-
script - tests - living standard
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);
var p = new URLSearchParams('a=1&b=2');
- URL:
href
,origin
,protocol
,username
,password
,host
,hostname
,port
,pathname
,search
,searchParams
,hash
- URLSearchParams:
append(name, value)
,delete(name)
,get(name)
,getAll(name)
,has(name)
,set(name, value)
,entries()
,keys()
,values()
,forEach(callback)
and[Symbol.iterator]()
(if defined)
script - demo page - draft spec (also)
KeyboardEvent: code
, key
, location
, KeyboardEvent.queryKeyCap(code)
IE7- only: Call window.identifyKey(keyboardEvent);
in keydown
/keyup
handlers before accessing above properties.
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);