youmightnotneedjquery.com Open in urlscan Pro
185.199.110.153  Public Scan

Submitted URL: http://youmightnotneedjquery.com/
Effective URL: https://youmightnotneedjquery.com/
Submission: On October 28 via manual from US — Scanned from DE

Form analysis 0 forms found in the DOM

Text Content

 * AJAX
   * JSON
   * Load
   * Post
   * Request
 * Effects
   * Fade In
   * Fade Out
   * Hide
   * Show
   * Toggle
 * Elements
   * Add Class
   * After
   * Append
   * Append To
   * Before
   * Children
   * Clone
   * Closest
   * Contains
   * Contains Selector
   * Contents
   * Create Elements
   * Each
   * Empty
   * Filter
   * Find Children
   * Find Elements
   * Find Selector
   * First
   * Get Attributes
   * Get Height
   * Get HTML
   * Get Outer HTML
   * Get Style
   * Get Text
   * Get Width
   * Has Class
   * Index
   * Inner Height
   * Inner Width
   * Last
   * Matches
   * Matches Selector
   * Next
   * Offset
   * Offset Parent
   * Outer Height
   * Outer Height With Margin
   * Outer Width
   * Outer Width With Margin
   * Parent
   * Parents
   * Position
   * Position Relative To Viewport
   * Prepend
   * Prev
   * Remove
   * Remove Attributes
   * Remove Class
   * Replace From HTML
   * Scroll Left
   * Scroll Top
   * Serialize
   * Set Attributes
   * Set Height
   * Set HTML
   * Set Style
   * Set Text
   * Set Width
   * Siblings
   * Toggle Class
   * Unwrap
   * Val
   * Wrap
 * Events
   * Click
   * Delegate
   * Off
   * On
   * Ready
   * Trigger Custom
   * Trigger Native
 * Utils
   * Array Each
   * Bind
   * Deep Extend
   * Extend
   * Index Of
   * Is Array
   * Is Numeric
   * Map
   * Now
   * Object Each
   * Parse HTML
   * Parse JSON
   * Slice
   * To Array
   * Trim
   * Type


YOU MIGHT NOT NEED JQUERY

jQuery and its cousins are great, and by all means use them if it makes it
easier to develop your application.

If you're developing a library on the other hand, please take a moment to
consider if you actually need jQuery as a dependency. Maybe you can include a
few lines of utility code, and forgo the requirement. If you're only targeting
more modern browsers, you might not need anything more than what the browser
ships with.

At the very least, make sure you know what jQuery is doing for you, and what
it's not. Some developers believe that jQuery is protecting us from a great
demon of browser incompatibility when, in truth, post-IE8, browsers are pretty
easy to deal with on their own; and after the Internet Explorer era, the
browsers do even more.

★ Star on Github 13,811
Do you need to support IE?
What's the oldest version of IE you need to support?

891011

Your search didn't match any comparisons.


AJAX


ALTERNATIVES:

 * fetch


JSON

JQUERY

📋

$.getJSON('/my/url', function (data) {});


IE8+

📋

var request = new XMLHttpRequest();
request.open('GET', '/my/url', true);

request.onreadystatechange = function () {
  if (this.readyState === 4) {
    if (this.status >= 200 && this.status < 400) {
      // Success!
      var data = JSON.parse(this.responseText);
    } else {
      // Error :(
    }
  }
};

request.send();
request = null;


IE9+

📋

var request = new XMLHttpRequest();
request.open('GET', '/my/url', true);

request.onload = function () {
  if (request.status >= 200 && request.status < 400) {
    // Success!
    var data = JSON.parse(request.responseText);
  } else {
    // We reached our target server, but it returned an error
  }
};

request.onerror = function () {
  // There was a connection error of some sort
};

request.send();


IE10+

📋

var request = new XMLHttpRequest();
request.open('GET', '/my/url', true);

request.onload = function () {
  if (this.status >= 200 && this.status < 400) {
    // Success!
    var data = JSON.parse(this.response);
  } else {
    // We reached our target server, but it returned an error
  }
};

request.onerror = function () {
  // There was a connection error of some sort
};

request.send();


MODERN

📋

const response = await fetch('/my/url');
const data = await response.json();



LOAD

JQUERY

📋

$('#some.selector').load('/path/to/template.html');


IE8+

📋

function load(selector, path) {
  var request = new XMLHttpRequest();
  request.open('GET', path, true);
  request.onreadystatechange = function () {
    if (this.readyState === 4) {
      if (this.status >= 200 && this.status < 400) {
        // Success!
        var elements = document.querySelector(selector);
        for (var i = 0; i < elements.length; i++) {
          elements[i].innerHTML = this.responseText;
        }
      } else {
        // Error :(
      }
    }
  };
}

load('#some.selector', '/path/to/template.html');


MODERN

📋

const response = await fetch('/path/to/template.html');
const body = await response.text();

document.querySelector('#some.selector').innerHTML = body;



POST

JQUERY

📋

$.ajax({
  type: 'POST',
  url: '/my/url',
  data: data
});


IE8+

📋

var request = new XMLHttpRequest();
request.open('POST', '/my/url', true);
request.setRequestHeader(
  'Content-Type',
  'application/x-www-form-urlencoded; charset=UTF-8'
);
request.send(data);


MODERN

📋

await fetch('/my/url', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(data)
});



REQUEST

JQUERY

📋

$.ajax({
  type: 'GET',
  url: '/my/url',
  success: function (resp) {},
  error: function () {}
});


IE8+

📋

function request(success, error) {
  var request = new XMLHttpRequest();
  request.open('GET', '/my/url', true);

  request.onreadystatechange = function () {
    if (this.readyState === 4) {
      if (this.status >= 200 && this.status < 400) {
        // Success! If you expect this to be JSON, use JSON.parse!
        success(this.responseText, this.status);
      } else {
        error();
      }
    }
  };

  request.send();
}


IE9+

📋

function request(success, error) {
  var request = new XMLHttpRequest();
  request.open('GET', '/my/url', true);

  request.onload = function () {
    if (this.status >= 200 && this.status < 400) {
      // Success! If you expect this to be JSON, use JSON.parse!
      success(this.responseText, this.status);
    } else {
      // We reached our target server, but it returned an error
      error();
    }
  };

  request.onerror = function () {
    error();
  };

  request.send();
}


MODERN

📋

const response = await fetch('/my/url');

if (!response.ok) {
}

const body = await response.text();



EFFECTS


ALTERNATIVES:

 * animate.css
 * move.js
 * velocity.js


FADE IN

JQUERY

📋

$(el).fadeIn();


IE8+

📋

function fadeIn(el, speed = 400) {
  var opacity = 0;

  el.style.opacity = 0;
  el.style.filter = '';

  var last = +new Date();
  var tick = function () {
    opacity += (new Date() - last) / speed;
    if (opacity > 1) opacity = 1;
    el.style.opacity = opacity;
    el.style.filter = 'alpha(opacity=' + (100 * opacity || 0) + ')';

    last = +new Date();

    if (opacity < 1) {
      (window.requestAnimationFrame && requestAnimationFrame(tick)) ||
        setTimeout(tick, 16);
    }
  };

  tick();
}

fadeIn(el);


IE9+

📋

function fadeIn(el, speed = 400) {
  el.style.opacity = 0;

  var last = +new Date();
  var tick = function () {
    el.style.opacity = +el.style.opacity + (new Date() - last) / speed;
    if (opacity > 1) opacity = 1;
    last = +new Date();

    if (+el.style.opacity < 1) {
      (window.requestAnimationFrame && requestAnimationFrame(tick)) ||
        setTimeout(tick, 16);
    }
  };

  tick();
}

fadeIn(el);


IE10+

📋

el.classList.add('show');
el.classList.remove('hide');


📋

.show {
  transition: opacity 400ms;
}
.hide {
  opacity: 0;
}


MODERN

📋

el.classList.replace('show', 'hide');


📋

.show {
  transition: opacity 400ms;
}
.hide {
  opacity: 0;
}



FADE OUT

JQUERY

📋

$(el).fadeOut();


IE8+

📋

function fadeOut(el, speed = 400) {
  var opacity = 1;

  el.style.opacity = 1;
  el.style.filter = '';

  var last = +new Date();
  var tick = function () {
    opacity -= (new Date() - last) / speed;
    if (opacity < 0) opacity = 0;
    el.style.opacity = opacity;
    el.style.filter = 'alpha(opacity=' + 100 * opacity + ')';

    last = +new Date();

    if (opacity > 0) {
      (window.requestAnimationFrame && requestAnimationFrame(tick)) ||
        setTimeout(tick, 16);
    }
  };

  tick();
}

fadeOut(el);


IE9+

📋

function fadeOut(el, speed = 400) {
  el.style.opacity = 1;

  var last = +new Date();
  var tick = function () {
    el.style.opacity = +el.style.opacity - (new Date() - last) / speed;
    if (opacity < 0) opacity = 0;
    last = +new Date();

    if (+el.style.opacity > 0) {
      (window.requestAnimationFrame && requestAnimationFrame(tick)) ||
        setTimeout(tick, 16);
    }
  };

  tick();
}

fadeOut(el);


IE10+

📋

el.classList.add('hide');
el.classList.remove('show');


📋

.show {
  opacity: 1;
}
.hide {
  opacity: 0;
  transition: opacity 400ms;
}


MODERN

📋

el.classList.replace('hide', 'show');


📋

.show {
  opacity: 1;
}
.hide {
  opacity: 0;
  transition: opacity 400ms;
}



HIDE

JQUERY

📋

$(el).hide();


IE8+

📋

el.style.display = 'none';



SHOW

JQUERY

📋

$(el).show();


IE8+

📋

el.style.display = '';



TOGGLE

JQUERY

📋

$(el).toggle();


IE8+

📋

function toggle(el) {
  if (el.style.display == 'none') {
    el.style.display = '';
  } else {
    el.style.display = 'none';
  }
}



ELEMENTS


ALTERNATIVES:

 * bonzo
 * $dom


ADD CLASS

JQUERY

📋

$(el).addClass(className);


IE8+

📋

if (el.classList) {
  el.classList.add(className);
} else {
  var current = el.className,
    found = false;
  var all = current.split(' ');
  for (var i = 0; i < all.length, !found; i++) found = all[i] === className;
  if (!found) {
    if (current === '') el.className = className;
    else el.className += ' ' + className;
  }
}


IE10+

📋

el.classList.add(className);



AFTER

JQUERY

📋

$(target).after(element);


IE8+

📋

target.insertAdjacentElement('afterend', element);


MODERN

📋

target.after(element);



APPEND

JQUERY

📋

$(parent).append(el);


IE8+

📋

parent.appendChild(el);


MODERN

📋

parent.append(el);



APPEND TO

JQUERY

📋

$(el).appendTo(parent);


IE8+

📋

parent.appendChild(el);


MODERN

📋

parent.append(el);



BEFORE

JQUERY

📋

$(target).before(element);


IE8+

📋

target.insertAdjacentElement('beforebegin', element);


MODERN

📋

target.before(el);



CHILDREN

JQUERY

📋

$(el).children();


IE8+

📋

var children = [];
for (var i = el.children.length; i--; ) {
  // Skip comment nodes on IE8
  if (el.children[i].nodeType != 8) children.unshift(el.children[i]);
}


IE9+

📋

el.children;



CLONE

JQUERY

📋

$(el).clone();


IE8+

📋

el.cloneNode(true);



CLOSEST

JQUERY

📋

$(el).closest(sel);


IE8+

📋

function closest(el, sel) {
  Element.prototype.matches ||
    (Element.prototype.matches =
      Element.prototype.matchesSelector ||
      Element.prototype.mozMatchesSelector ||
      Element.prototype.msMatchesSelector ||
      Element.prototype.oMatchesSelector ||
      Element.prototype.webkitMatchesSelector ||
      function (b) {
        b = (this.document || this.ownerDocument).querySelectorAll(b);
        for (var a = b.length; 0 <= --a && b.item(a) !== this; );
        return -1 < a;
      });
  Element.prototype.closest ||
    (Element.prototype.closest = function (b) {
      var a = this;
      do {
        if (a.matches(b)) return a;
        a = a.parentElement || a.parentNode;
      } while (null !== a && 1 === a.nodeType);
      return null;
    });
  return el.closest(sel);
}

closest(el, sel);


IE9+

📋

function closest(el, sel) {
  Element.prototype.matches ||
    (Element.prototype.matches =
      Element.prototype.msMatchesSelector ||
      Element.prototype.webkitMatchesSelector);
  Element.prototype.closest ||
    (Element.prototype.closest = function (c) {
      var a = this;
      do {
        if (a.matches(c)) return a;
        a = a.parentElement || a.parentNode;
      } while (null !== a && 1 === a.nodeType);
      return null;
    });
  return el.closest(sel);
}

closest(el, sel);


IE10+

📋

el.closest(sel);



CONTAINS

JQUERY

📋

$.contains(el, child);


IE8+

📋

el !== child && el.contains(child);


MODERN

📋

node.contains(anotherNode);



CONTAINS SELECTOR

ALTERNATIVES:

 * xpath

JQUERY

📋

$("div:contains('my text')");


MODERN

📋

[...document.querySelectorAll('div')].filter((el) =>
  el.textContent.includes('my text')
);



CONTENTS

JQUERY

📋

$(el).contents();


MODERN

📋

el.childNodes;



CREATE ELEMENTS

JQUERY

📋

$('<div>Hello World!</div>');


IE8+

📋

function generateElements(html) {
  var div = document.createElement('div');
  div.innerHTML = html;
  return div.children;
}

generateElements('<div>Hello World!</div>');


MODERN

📋

function generateElements(html) {
  const template = document.createElement('template');
  template.innerHTML = html.trim();
  return template.content.children;
}

generateElements('<div>Hello World!</div>');



EACH

JQUERY

📋

$(selector).each(function (i, el) {});


IE8+

📋

function forEachElement(selector, fn) {
  var elements = document.querySelectorAll(selector);
  for (var i = 0; i < elements.length; i++) fn(elements[i], i);
}

forEachElement(selector, function (el, i) {});


IE9+

📋

var elements = document.querySelectorAll(selector);
Array.prototype.forEach.call(elements, function (el, i) {});


MODERN

📋

document.querySelectorAll(selector).forEach((el, i) => {});



EMPTY

JQUERY

📋

$(el).empty();


IE8+

📋

while (el.firstChild) el.removeChild(el.firstChild);


MODERN

📋

el.replaceChildren();



FILTER

JQUERY

📋

$(selector).filter(filterFn);


IE8+

📋

function filter(selector, filterFn) {
  var elements = document.querySelectorAll(selector);
  var out = [];
  for (var i = elements.length; i--; ) {
    if (filterFn(elements[i])) out.unshift(elements[i]);
  }
  return out;
}

filter(selector, filterFn);


IE9+

📋

Array.prototype.filter.call(document.querySelectorAll(selector), filterFn);


MODERN

📋

[...document.querySelectorAll(selector)].filter(filterFn);



FIND CHILDREN

JQUERY

📋

$(el).find(selector);


IE8+

📋

el.querySelectorAll(selector);


MODERN

📋

// For direct descendants only, see https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelectorAll#user_notes
el.querySelectorAll(`:scope ${selector}`);



FIND ELEMENTS

ALTERNATIVES:

 * qwery
 * sizzle

JQUERY

📋

$('.my #awesome selector');


IE8+

📋

document.querySelectorAll('.my #awesome selector');



FIND SELECTOR

JQUERY

📋

$(el).find(selector).length;


IE8+

📋

!!el.querySelector(selector);



FIRST

JQUERY

📋

$(el).first();


IE8+

📋

document.querySelector(el);



GET ATTRIBUTES

JQUERY

📋

$(el).attr('tabindex');


IE8+

📋

el.getAttribute('tabindex');



GET HEIGHT

JQUERY

📋

$(el).height();


IE8+

📋

function getHeight(el) {
  var d = /^\d+(px)?$/i;
  if (window.getComputedStyle)
    el = parseFloat(getComputedStyle(el, null).height.replace('px', ''));
  else {
    var c = el.currentStyle.height;
    if (d.test(c)) el = parseInt(c);
    else {
      d = el.style.left;
      var e = el.runtimeStyle.left;
      el.runtimeStyle.left = el.currentStyle.left;
      el.style.left = c || 0;
      c = el.style.pixelLeft;
      el.style.left = d;
      el.runtimeStyle.left = e;
      el = c;
    }
  }
  return el;
}

getHeight(el);


IE9+

📋

parseFloat(getComputedStyle(el, null).height.replace('px', ''));


MODERN

📋

el.getBoundingClientRect().height;



GET HTML

JQUERY

📋

$(el).html();


IE8+

📋

el.innerHTML;



GET OUTER HTML

JQUERY

📋

$(el).prop('outerHTML');


IE8+

📋

el.outerHTML;



GET STYLE

JQUERY

📋

$(el).css(ruleName);


IE8+

📋

// Varies based on the properties being retrieved, some can be retrieved from el.currentStyle
// https://github.com/jonathantneal/Polyfills-for-IE8/blob/master/getComputedStyle.js


IE9+

📋

getComputedStyle(el)[ruleName];



GET TEXT

JQUERY

📋

$(el).text();


IE8+

📋

el.textContent || el.innerText;


IE9+

📋

el.textContent;



GET WIDTH

JQUERY

📋

$(el).width();


IE8+

📋

function getWidth(el) {
  var d = /^\d+(px)?$/i;
  if (window.getComputedStyle)
    el = parseFloat(getComputedStyle(el, null).width.replace('px', ''));
  else {
    var c = el.currentStyle.width;
    if (d.test(c)) el = parseInt(c);
    else {
      d = el.style.left;
      var e = el.runtimeStyle.left;
      el.runtimeStyle.left = el.currentStyle.left;
      el.style.left = c || 0;
      c = el.style.pixelLeft;
      el.style.left = d;
      el.runtimeStyle.left = e;
      el = c;
    }
  }
  return el;
}

getWidth(el);


IE9+

📋

parseFloat(getComputedStyle(el, null).width.replace('px', ''));


MODERN

📋

el.getBoundingClientRect().width;



HAS CLASS

JQUERY

📋

$(el).hasClass(className);


IE8+

📋

if (el.classList) el.classList.contains(className);
else new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className);


IE10+

📋

el.classList.contains(className);



INDEX

JQUERY

📋

$(el).index();


IE8+

📋

function index(el) {
  if (!el) return -1;
  var i = 0;
  while (el) {
    el = el.previousSibling;
    if (el && el.nodeType === 1) i++;
  }
  return i;
}


IE9+

📋

function index(el) {
  if (!el) return -1;
  var i = 0;
  while ((el = el.previousElementSibling)) {
    i++;
  }
  return i;
}


MODERN

📋

[...el.parentNode.children].indexOf(el);



INNER HEIGHT

JQUERY

📋

$(el).innerHeight();
$(el).innerHeight(150);


MODERN

📋

function innerHeight(el, value) {
  if (value === undefined) {
    return el.clientHeight;
  } else {
    el.style.height = value;
  }
}

innerHeight(el);
innerHeight(el, 150);



INNER WIDTH

JQUERY

📋

$(el).innerWidth();
$(el).innerWidth(150);


MODERN

📋

function innerWidth(el, value) {
  if (value === undefined) {
    return el.clientWidth;
  } else {
    el.style.width = value;
  }
}

innerWidth(el);
innerWidth(el, 150);



LAST

JQUERY

📋

$(el).last();


IE8+

📋

var els = document.querySelectorAll(el);
els[els.length - 1];


MODERN

📋

const els = document.querySelectorAll(el);
els.at(-1);



MATCHES

JQUERY

📋

$(el).is($(otherEl));


IE8+

📋

el === otherEl;



MATCHES SELECTOR

JQUERY

📋

$(el).is('.my-class');


IE8+

📋

var matches = function (el, selector) {
  var _matches =
    el.matches ||
    el.matchesSelector ||
    el.msMatchesSelector ||
    el.mozMatchesSelector ||
    el.webkitMatchesSelector ||
    el.oMatchesSelector;

  if (_matches) {
    return _matches.call(el, selector);
  } else {
    if (el.parentNode === null) return false;
    var nodes = el.parentNode.querySelectorAll(selector);
    for (var i = nodes.length; i--; ) {
      if (nodes[i] === el) return true;
    }
    return false;
  }
};

matches(el, '.my-class');


IE9+

📋

var matches = function (el, selector) {
  return (
    el.matches ||
    el.matchesSelector ||
    el.msMatchesSelector ||
    el.mozMatchesSelector ||
    el.webkitMatchesSelector ||
    el.oMatchesSelector
  ).call(el, selector);
};

matches(el, '.my-class');


MODERN

📋

el.matches('.my-class');



NEXT

JQUERY

📋

$(el).next();


IE8+

📋

// nextSibling can include text nodes
function nextElementSibling(el) {
  do {
    el = el.nextSibling;
  } while (el && el.nodeType !== 1);
  return el;
}

el.nextElementSibling || nextElementSibling(el);


IE9+

📋

el.nextElementSibling;



OFFSET

JQUERY

📋

$(el).offset();


IE8+

📋

function offset(el) {
  var docElem = document.documentElement;
  var rect = el.getBoundingClientRect();
  return {
    top:
      rect.top +
      (window.pageYOffset || docElem.scrollTop) -
      (docElem.clientTop || 0),
    left:
      rect.left +
      (window.pageXOffset || docElem.scrollLeft) -
      (docElem.clientLeft || 0)
  };
}


IE9+

📋

function offset(el) {
  box = el.getBoundingClientRect();
  docElem = document.documentElement;
  return {
    top: box.top + window.pageYOffset - docElem.clientTop,
    left: box.left + window.pageXOffset - docElem.clientLeft
  };
}



OFFSET PARENT

JQUERY

📋

$(el).offsetParent();


IE8+

📋

el.offsetParent || el;



OUTER HEIGHT

JQUERY

📋

$(el).outerHeight();


IE8+

📋

el.offsetHeight;



OUTER HEIGHT WITH MARGIN

JQUERY

📋

$(el).outerHeight(true);


IE8+

📋

function outerHeight(el) {
  var height = el.offsetHeight;
  var style = el.currentStyle || getComputedStyle(el);

  height += parseFloat(style.marginTop) + parseFloat(style.marginBottom);
  return height;
}

outerHeight(el);


IE9+

📋

function outerHeight(el) {
  var height = el.offsetHeight;
  var style = getComputedStyle(el);

  height += parseFloat(style.marginTop) + parseFloat(style.marginBottom);
  return height;
}

outerHeight(el);


MODERN

📋

function outerHeight(el) {
  const style = getComputedStyle(el);

  return (
    el.getBoundingClientRect().height +
    parseFloat(style.getPropertyValue('marginTop')) +
    parseFloat(style.getPropertyValue('marginBottom'))
  );
}

outerHeight(el);



OUTER WIDTH

JQUERY

📋

$(el).outerWidth();


IE8+

📋

el.offsetWidth;



OUTER WIDTH WITH MARGIN

JQUERY

📋

$(el).outerWidth(true);


IE8+

📋

function outerWidth(el) {
  var width = el.offsetWidth;
  var style = el.currentStyle || getComputedStyle(el);

  width += parseFloat(style.marginLeft) + parseFloat(style.marginRight);
  return width;
}

outerWidth(el);


IE9+

📋

function outerWidth(el) {
  var width = el.offsetWidth;
  var style = getComputedStyle(el);

  width += parseFloat(style.marginLeft) + parseFloat(style.marginRight);
  return width;
}

outerWidth(el);


MODERN

📋

function outerWidth(el) {
  const style = getComputedStyle(el);

  return (
    el.getBoundingClientRect().width +
    parseFloat(style.getPropertyValue('marginLeft')) +
    parseFloat(style.getPropertyValue('marginRight'))
  );
}

outerWidth(el);



PARENT

JQUERY

📋

$(el).parent();


IE8+

📋

el.parentNode;



PARENTS

JQUERY

📋

$(el).parents(selector);


IE9+

📋

function parents(el, selector) {
  var parents = [];
  while ((el = el.parentNode) && el !== document) {
    // See "Matches Selector" above
    if (!selector || matches(el, selector)) parents.unshift(el);
  }
  return parents;
}


MODERN

📋

function parents(el, selector) {
  const parents = [];
  while ((el = el.parentNode) && el !== document) {
    if (!selector || el.matches(selector)) parents.unshift(el);
  }
  return parents;
}



POSITION

JQUERY

📋

$(el).position();


IE8+

📋

function position(el) {
  var box = el.getBoundingClientRect();
  var docElem = document.documentElement;
  var marginLeft = 0;
  var marginTop = 0;
  if (typeof getComputedStyle === 'function') {
    var style = window.getComputedStyle(el);
    marginLeft = parseInt(style.marginLeft, 10);
    marginTop = parseInt(style.marginTop, 10);
  } else if (el.currentStyle) {
    marginLeft = el.currentStyle['marginLeft']
      ? parseInt(el.currentStyle['marginLeft'], 10)
      : 0;
    marginTop = el.currentStyle['marginTop']
      ? parseInt(el.currentStyle['marginTop'], 10)
      : 0;
  }
  return {
    top: box.top + (window.pageYOffset || docElem.scrollTop) - marginTop,
    left: box.left + (window.pageXOffset || docElem.scrollLeft) - marginLeft
  };
}


MODERN

📋

function position(el) {
  const {top, left} = el.getBoundingClientRect();
  const {marginTop, marginLeft} = getComputedStyle(el);
  return {
    top: top - parseInt(marginTop, 10),
    left: left - parseInt(marginLeft, 10)
  };
}



POSITION RELATIVE TO VIEWPORT

JQUERY

📋

function offset(el) {
  var offset = $(el).offset();
  return {
    top: offset.top - document.body.scrollTop,
    left: offset.left - document.body.scrollLeft
  };
}


IE8+

📋

el.getBoundingClientRect();



PREPEND

JQUERY

📋

$(parent).prepend(el);


IE8+

📋

parent.insertBefore(el, parent.firstChild);


MODERN

📋

parent.prepend(el);



PREV

JQUERY

📋

$(el).prev();
// Or, with an optional selector
$(el).prev('.my-selector');


IE8+

📋

// prevSibling can include text nodes
function previousElementSibling(el) {
  do {
    el = el.previousSibling;
  } while (el && el.nodeType !== 1);
  return el;
}

el.previousElementSibling || previousElementSibling(el);


IE9+

📋

el.previousElementSibling;


MODERN

📋

function prev(el, selector) {
  if (selector) {
    let previous = el.previousElementSibling;
    while (previous && !previous.matches(selector)) {
      previous = previous.previousElementSibling;
    }
    return previous;
  } else {
    return el.previousElementSibling;
  }
}

prev(el);
// Or, with an optional selector
prev(el, '.my-selector');



REMOVE

JQUERY

📋

$(el).remove();

// multiple elements
$(selector).remove();


IE8+

📋

if (el.parentNode !== null) {
  el.parentNode.removeChild(el);
}


MODERN

📋

el.remove();

// multiple elements
for (const el of [...document.querySelectorAll(selector)]) {
  el.remove();
}



REMOVE ATTRIBUTES

JQUERY

📋

$(el).removeAttr('tabindex');


IE8+

📋

el.removeAttribute('tabindex');



REMOVE CLASS

JQUERY

📋

$(el).removeClass(className);


IE8+

📋

function removeClass(el, className) {
  var classes = className.split(' ');
  for (var i = 0; i < classes.length; i++) {
    if (el.classList) {
      el.classList.remove(classes[i]);
    } else {
      el.className = el.className
        .replace(new RegExp('(?:^|\\s)' + classes[i] + '(?:\\s|$)'), ' ')
        .replace(new RegExp(/^\s+|\s+$/g), '');
    }
  }
}


IE10+

📋

el.classList.remove(className);



REPLACE FROM HTML

JQUERY

📋

$(el).replaceWith(string);


IE8+

📋

el.outerHTML = string;



SCROLL LEFT

JQUERY

📋

$(window).scrollLeft();


MODERN

📋

function scrollLeft(el, value) {
  if (value === undefined) {
    return el.pageXOffset;
  } else {
    if (el === window || el.nodeType === 9) {
      el.scrollTo(value, el.pageYOffset);
    } else {
      el.pageXOffset = value;
    }
  }
}



SCROLL TOP

JQUERY

📋

$(window).scrollTop();


MODERN

📋

function scrollTop(el, value) {
  if (value === undefined) {
    return el.pageYOffset;
  } else {
    if (el === window || el.nodeType === 9) {
      el.scrollTo(el.pageXOffset, value);
    } else {
      el.pageYOffset = value;
    }
  }
}



SERIALIZE

JQUERY

📋

$(formElement).serialize();


MODERN

📋

new URLSearchParams(new FormData(formElement)).toString();



SET ATTRIBUTES

JQUERY

📋

$(el).attr('tabindex', 3);


IE8+

📋

el.setAttribute('tabindex', 3);



SET HEIGHT

JQUERY

📋

$(el).height(val);


IE8+

📋

function setHeight(el, val) {
  if (typeof val === 'function') val = val();
  if (typeof val === 'string') el.style.height = val;
  else el.style.height = val + 'px';
}

setHeight(el, val);



SET HTML

JQUERY

📋

$(el).html(string);


IE8+

📋

el.innerHTML = string;



SET STYLE

JQUERY

📋

$(el).css('border-width', '20px');


IE8+

📋

// Use a class if possible
el.style.borderWidth = '20px';



SET TEXT

JQUERY

📋

$(el).text(string);


IE8+

📋

if (el.textContent !== undefined) el.textContent = string;
else el.innerText = string;


IE9+

📋

el.textContent = string;



SET WIDTH

JQUERY

📋

$(el).width(val);


IE8+

📋

function setWidth(el, val) {
  if (typeof val === 'function') val = val();
  if (typeof val === 'string') el.style.width = val;
  else el.style.width = val + 'px';
}

setWidth(el, val);



SIBLINGS

JQUERY

📋

$(el).siblings();


IE8+

📋

var siblings = function (el) {
  if (el.parentNode === null) return [];

  var siblingElements = Array.prototype.slice.call(el.parentNode.children);

  for (var i = siblingElements.length; i--; ) {
    if (siblingElements[i] === el) {
      return siblingElements.splice(i, 1);
    }
  }

  return siblingElements;
};

siblings(el);


IE9+

📋

var siblings = function (el) {
  if (el.parentNode === null) return [];

  return Array.prototype.filter.call(el.parentNode.children, function (child) {
    return child !== el;
  });
};

siblings(el);


MODERN

📋

[...el.parentNode.children].filter((child) => child !== el);



TOGGLE CLASS

JQUERY

📋

$(el).toggleClass(className);


IE8+

📋

if (el.classList) {
  el.classList.toggle(className);
} else {
  var classes = el.className.split(' ');
  var existingIndex = -1;
  for (var i = classes.length; i--; ) {
    if (classes[i] === className) existingIndex = i;
  }

  if (existingIndex >= 0) classes.splice(existingIndex, 1);
  else classes.push(className);

  el.className = classes.join(' ');
}


IE9+

📋

if (el.classList) {
  el.classList.toggle(className);
} else {
  var classes = el.className.split(' ');
  var existingIndex = classes.indexOf(className);

  if (existingIndex >= 0) classes.splice(existingIndex, 1);
  else classes.push(className);

  el.className = classes.join(' ');
}


IE10+

📋

el.classList.toggle(className);



UNWRAP

JQUERY

📋

$(el).unwrap();


MODERN

📋

el.replaceWith(...el.childNodes);



VAL

JQUERY

📋

$(el).val();


MODERN

📋

function val(el) {
  if (el.options && el.multiple) {
    return el.options
      .filter((option) => option.selected)
      .map((option) => option.value);
  } else {
    return el.value;
  }
}



WRAP

JQUERY

📋

el.wrap('<div></div>');


MODERN

📋

function wrap(el) {
  const wrappingElement = document.createElement('div');
  el.replaceWith(wrappingElement);
  wrappingElement.appendChild(el);
}



EVENTS


ALTERNATIVES:

 * ftdomdelegate
 * defer
 * modules


CLICK

JQUERY

📋

$(el).click(function () {});


IE8+

📋

var onClick = function (element, handler) {
  if (element.addEventListener) {
    element.addEventListener('click', handler, false);
  } else {
    element.attachEvent('onclick', handler);
  }
};

onClick(el, function () {});


IE9+

📋

el.addEventListener('click', function () {});


MODERN

📋

el.addEventListener('click', () => {});



DELEGATE

JQUERY

📋

$(document).on(eventName, elementSelector, handler);


IE8+

📋

document.addEventListener(
  eventName,
  function (e) {
    // loop parent nodes from the target to the delegation node
    for (
      var target = e.target;
      target && target != this;
      target = target.parentNode
    ) {
      if (target.matches(elementSelector)) {
        handler.call(target, e);
        break;
      }
    }
  },
  false
);


MODERN

📋

document.addEventListener(eventName, (event) => {
  if (event.target.closest(elementSelector)) {
    handler.call(event.target, event);
  }
});



OFF

JQUERY

📋

$(el).off(eventName, eventHandler);


IE8+

📋

function removeEventListener(el, eventName, handler) {
  if (el.removeEventListener) el.removeEventListener(eventName, handler);
  else el.detachEvent('on' + eventName, handler);
}

removeEventListener(el, eventName, handler);


IE9+

📋

el.removeEventListener(eventName, eventHandler);



ON

JQUERY

📋

$(el).on(eventName, eventHandler);
// Or when you want to delegate event handling
$(el).on(eventName, selector, eventHandler);


IE8+

📋

function addEventListener(el, eventName, handler) {
  if (el.addEventListener) {
    el.addEventListener(eventName, handler);
    return handler;
  } else {
    var wrappedHandler = function (event) {
      handler.call(el, event);
    };
    el.attachEvent('on' + eventName, wrappedHandler);
    return wrappedHandler;
  }
}

// Use the return value to remove that event listener, see #off
var handlerToRemove = addEventListener(el, eventName, handler);


IE9+

📋

function addEventListener(el, eventName, eventHandler, selector) {
  if (selector) {
    var wrappedHandler = function (e) {
      if (e.target && e.target.matches(selector)) {
        eventHandler(e);
      }
    };
    el.addEventListener(eventName, wrappedHandler);
    return wrappedHandler;
  } else {
    el.addEventListener(eventName, eventHandler);
    return eventHandler;
  }
}

// Use the return value to remove that event listener, see #off
addEventListener(el, eventName, eventHandler);
// Or when you want to delegate event handling
addEventListener(el, eventName, eventHandler, selector);


MODERN

📋

function addEventListener(el, eventName, eventHandler, selector) {
  if (selector) {
    const wrappedHandler = (e) => {
      if (e.target && e.target.matches(selector)) {
        eventHandler(e);
      }
    };
    el.addEventListener(eventName, wrappedHandler);
    return wrappedHandler;
  } else {
    el.addEventListener(eventName, eventHandler);
    return eventHandler;
  }
}

// Use the return value to remove that event listener, see #off
addEventListener(el, eventName, eventHandler);
// Or when you want to delegate event handling
addEventListener(el, eventName, eventHandler, selector);



READY

JQUERY

📋

$(document).ready(function () {});


IE8+

📋

function ready(fn) {
  if (document.readyState != 'loading') {
    fn();
  } else if (document.addEventListener) {
    document.addEventListener('DOMContentLoaded', fn);
  } else {
    document.attachEvent('onreadystatechange', function () {
      if (document.readyState != 'loading') fn();
    });
  }
}


IE9+

📋

function ready(fn) {
  if (
    document.attachEvent
      ? document.readyState === 'complete'
      : document.readyState !== 'loading'
  ) {
    fn();
  } else {
    document.addEventListener('DOMContentLoaded', fn);
  }
}


MODERN

📋

function ready(fn) {
  if (document.readyState !== 'loading') {
    fn();
  } else {
    document.addEventListener('DOMContentLoaded', fn);
  }
}



TRIGGER CUSTOM

ALTERNATIVES:

 * EventEmitter
 * Vine
 * microevent

JQUERY

📋

$(el).trigger('my-event', {some: 'data'});


IE8+

📋

// Custom events are not natively supported, so you have to hijack a random
// event.
//
// Just use jQuery.


IE9+

📋

if (window.CustomEvent && typeof window.CustomEvent === 'function') {
  var event = new CustomEvent('my-event', {detail: {some: 'data'}});
} else {
  var event = document.createEvent('CustomEvent');
  event.initCustomEvent('my-event', true, true, {some: 'data'});
}

el.dispatchEvent(event);


MODERN

📋

const event = new CustomEvent('my-event', {detail: {some: 'data'}});
el.dispatchEvent(event);



TRIGGER NATIVE

JQUERY

📋

$(el).trigger('focus');


IE8+

📋

function trigger(el, eventType) {
  if (typeof eventType === 'string' && typeof el[eventType] === 'function') {
    el[eventType]();
  } else if (eventType === 'string') {
    if (document.createEvent) {
      var event = document.createEvent('HTMLEvents');
      event.initEvent(eventType, true, false);
      el.dispatchEvent(event);
    } else {
      el.fireEvent('on' + eventType);
    }
  } else {
    el.dispatchEvent(eventType);
  }
}

// For a full list of event types: https://developer.mozilla.org/en-US/docs/Web/API/document.createEvent
trigger(el, 'focus');


IE9+

📋

function trigger(el, eventType) {
  if (typeof eventType === 'string' && typeof el[eventType] === 'function') {
    el[eventType]();
  } else {
    var event;
    if (eventType === 'string') {
      event = document.createEvent('HTMLEvents');
      event.initEvent(eventType, true, false);
    } else {
      event = eventType;
    }
    el.dispatchEvent(event);
  }
}

// For a full list of event types: https://developer.mozilla.org/en-US/docs/Web/API/document.createEvent
trigger(el, 'focus');


MODERN

📋

function trigger(el, eventType) {
  if (typeof eventType === 'string' && typeof el[eventType] === 'function') {
    el[eventType]();
  } else {
    const event =
      eventType === 'string'
        ? new Event(eventType, {bubbles: true})
        : eventType;
    el.dispatchEvent(event);
  }
}

trigger(el, 'focus');
// For a full list of event types: https://developer.mozilla.org/en-US/docs/Web/API/Event
trigger(el, new PointerEvent('pointerover'));



UTILS


ARRAY EACH

JQUERY

📋

$.each(array, function (i, item) {});


IE8+

📋

function forEach(array, fn) {
  for (var i = 0; i < array.length; i++) fn(array[i], i);
}

forEach(array, function (item, i) {});


IE9+

📋

array.forEach(function (item, i) {});


MODERN

📋

array.forEach((item, i) => {});



BIND

JQUERY

📋

$.proxy(fn, context);


IE8+

📋

fn.apply(context, arguments);


IE9+

📋

fn.bind(context);



DEEP EXTEND

JQUERY

📋

$.extend(true, {}, objA, objB);


IE8+

📋

function deepExtend(out) {
  out = out || {};

  for (var i = 1; i < arguments.length; i++) {
    var obj = arguments[i];

    if (!obj) continue;

    for (var key in obj) {
      if (obj.hasOwnProperty(key)) {
        var rawType = Object.prototype.toString.call(obj[key]);
        if (rawType === '[object Object]') {
          out[key] = deepExtend(out[key], obj[key]);
        } else if (rawType === '[object Array]') {
          out[key] = deepExtend(new Array(obj[key].length), obj[key]);
        } else {
          out[key] = obj[key];
        }
      }
    }
  }

  return out;
}

deepExtend({}, objA, objB);


MODERN

📋

function deepExtend(out, ...arguments_) {
  if (!out) {
    return {};
  }

  for (const obj of arguments_) {
    if (!obj) {
      continue;
    }

    for (const [key, value] of Object.entries(obj)) {
      switch (Object.prototype.toString.call(value)) {
        case '[object Object]':
          out[key] = deepExtend(out[key], value);
          break;
        case '[object Array]':
          out[key] = deepExtend(new Array(value.length), value);
          break;
        default:
          out[key] = value;
      }
    }
  }

  return out;
}

deepExtend({}, objA, objB);



EXTEND

ALTERNATIVES:

 * Lodash
 * Underscore
 * ECMA6

JQUERY

📋

$.extend({}, objA, objB);


IE8+

📋

var extend = function (out) {
  out = out || {};

  for (var i = 1; i < arguments.length; i++) {
    if (!arguments[i]) continue;

    for (var key in arguments[i]) {
      if (arguments[i].hasOwnProperty(key)) out[key] = arguments[i][key];
    }
  }

  return out;
};

extend({}, objA, objB);


MODERN

📋

const result = {...objA, ...objB};



INDEX OF

JQUERY

📋

$.inArray(item, array);


IE8+

📋

function indexOf(array, item) {
  for (var i = 0; i < array.length; i++) {
    if (array[i] === item) return i;
  }
  return -1;
}

indexOf(array, item);


IE9+

📋

array.indexOf(item);



IS ARRAY

JQUERY

📋

$.isArray(arr);


IE8+

📋

isArray =
  Array.isArray ||
  function (arr) {
    return Object.prototype.toString.call(arr) == '[object Array]';
  };

isArray(arr);


IE9+

📋

Array.isArray(arr);



IS NUMERIC

JQUERY

📋

$.isNumeric(val);


IE8+

📋

function isNumeric(num) {
  if (typeof num === 'number') return num - num === 0;
  if (typeof num === 'string' && num.trim() !== '')
    return Number.isFinite ? Number.isFinite(+num) : isFinite(+num);
  return false;
}

isNumeric(val);


MODERN

📋

function isNumeric(num) {
  if (typeof num === 'number') return num - num === 0;
  if (typeof num === 'string' && num.trim() !== '')
    return Number.isFinite(+num);
  return false;
}

isNumeric(val);



MAP

JQUERY

📋

$.map(array, function (value, index) {});


IE8+

📋

function map(arr, fn) {
  var results = [];
  for (var i = 0; i < arr.length; i++) results.push(fn(arr[i], i));
  return results;
}

map(array, function (value, index) {});


IE9+

📋

array.map(function (value, index) {});


MODERN

📋

array.map((value, index) => {});



NOW

JQUERY

📋

$.now();


IE8+

📋

new Date().getTime();


IE9+

📋

Date.now();



OBJECT EACH

JQUERY

📋

$.each(obj, function (key, value) {});


IE8+

📋

function objectEach(obj, callback) {
  for (var key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      callback(key, obj[key]);
    }
  }
}

objectEach(obj, function (key, value) {});


MODERN

📋

for (const [key, value] of Object.entries(obj)) {
}



PARSE HTML

JQUERY

📋

$.parseHTML(htmlString);


IE8+

📋

var parseHTML = function (str) {
  var el = document.createElement('div');
  el.innerHTML = str;
  return el.childNodes;
};

parseHTML(htmlString);


IE9+

📋

var parseHTML = function (str) {
  var tmp = document.implementation.createHTMLDocument('');
  tmp.body.innerHTML = str;
  return Array.prototype.slice.call(tmp.body.childNodes);
};

parseHTML(htmlString);


MODERN

📋

function parseHTML(str) {
  const tmp = document.implementation.createHTMLDocument('');
  tmp.body.innerHTML = str;
  return [...tmp.body.childNodes];
}

parseHTML(htmlString);



PARSE JSON

JQUERY

📋

$.parseJSON(string);


IE8+

📋

JSON.parse(string);



SLICE

JQUERY

📋

$(els).slice(begin, end);


IE8+

📋

function slice(els, start, end) {
  var f = Array.prototype.slice;
  try {
    f.call(document.documentElement);
  } catch (h) {
    Array.prototype.slice = function (g, b) {
      b = 'undefined' !== typeof b ? b : this.length;
      if ('[object Array]' === Object.prototype.toString.call(this))
        return f.call(this, g, b);
      var e = [];
      var a = this.length;
      var c = g || 0;
      c = 0 <= c ? c : Math.max(0, a + c);
      var d = 'number' == typeof b ? Math.min(b, a) : a;
      0 > b && (d = a + b);
      d -= c;
      if (0 < d)
        if (((e = Array(d)), this.charAt))
          for (a = 0; a < d; a++) e[a] = this.charAt(c + a);
        else for (a = 0; a < d; a++) e[a] = this[c + a];
      return e;
    };
  }
  return els.slice(start, end);
}

slice(els, start, end);


IE9+

📋

els.slice(begin, end);



TO ARRAY

JQUERY

📋

$(selector).toArray();


IE8+

📋

function toArray(selector) {
  var array = [];
  var elements = document.querySelectorAll(selector);
  for (var i = 0; i < elements.length; i++) array.push(elements[i]);
  return array;
}


MODERN

📋

const array = [...document.querySelectorAll(selector)];



TRIM

JQUERY

📋

$.trim(string);


IE8+

📋

string.replace(/^\s+|\s+$/g, '');


IE9+

📋

string.trim();



TYPE

JQUERY

📋

$.type(obj);


IE8+

📋

Object.prototype.toString
  .call(obj)
  .replace(/^\[object (.+)\]$/, '$1')
  .toLowerCase();


Made by @adamfschwartz, @zackbloom and some engineer gamers at HubSpot.