/polyfill

JavaScript Polyfills, Shims and More

Primary LanguageJavaScriptOtherNOASSERTION

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.

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 present
    • element.dataset[key] = str - fails unless data-key attribute already present
  • Base64 utility methods (for IE9-)
    • encodedString = window.btoa(binaryString) - Base64 Encode
    • binaryString = 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-)
  • 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 - classListspec, relListspec
    • 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

// Adds the following properties to each KeyboardEvent:
event.code
event.key
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`, `key`, or `location` properties:
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