polyfill - JavaScript Polyfills, Shims and More
- 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.
Getting the Code
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")
Files
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:
Minification is done via http://javascript-minifier.com/
ECMAScript / JavaScript Polyfills
ECMAScript 5 - Most recent standard, supported by all modern browsers. Frozen.
ECMAScript 6 - Based on nearly complete draft standard. Should be stable apart from bug fixes.
ECMAScript proposed - Proposals for future editions of the standard. Here there be dragons.
JavaScript 1.X String Extras - ref
- String prototype:
trimLeft
, trimRight
, quote
HTML
script -
tests -
living standard
document.head
(for IE8-)- 'shiv' of newer HTML elements (
section
, aside
, etc), to fix parsing (for IE8-) dataset
and data-*
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
DOM
script -
tests -
living standard
- Selectors (for IE7-) - adapted from Paul Young
element = document.querySelector(selector)
elementArray = document.querySelectorAll(selector)
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
is window
, document
, or any element:
EventTarget.addEventListener(event, handler)
- for IE8+EventTarget.removeEventListener(event, handler)
- for IE8+
Event.target
Event.currentTarget
Event.eventPhase
Event.bubbles
Event.cancelable
Event.timeStamp
Event.defaultPrevented
Event.stopPropagation()
Event.cancelBubble()
- Non-standard Event helpers for IE7- - adapted from
QuirksMode
window.addEvent(EventTarget, event, handler)
window.removeEvent(EventTarget, event, handler)
- DOMTokenList -
classList
spec, relList
spec
tokenList = elem.classList
- for IE8+tokenList = elem.relList
- for IE8+tokenList.length
tokenList.item(index)
tokenList.contains(token)
tokenList.add(token)
tokenList.remove(token)
tokenList.toggle(token)
- Non-standard helpers for IE7-:
tokenList = window.getClassList(element)
tokenList = window.getRelList(element)
Fetch
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)
XMLHttpRequest
script -
tests -
living standard
Timing
script
CSS OM
script - spec
Polyfill for width
and height
in getBoundingClientRect()
in IE8-
URL API
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 objects have properties:
href
, origin
, protocol
, username
, password
, host
, hostname
, port
, pathname
, search
, searchParams
, hash
URLSearchParams objects have:
append(name, value)
delete(name)
get(name)
getAll(name)
has(name)
set(name, value)
entries()
, keys()
, values()
, forEach(callback)
and [Symbol.iterator]()
(if defined)
Keyboard Events
script -
demo page -
draft spec
event.code
event.key
event.location
KeyboardEvent.queryKeyCap(code);
window.identifyKey(keyboardEvent);
more details
Geolocation API
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);
Obsolete
Obsolete and Unmaintained Polyfills