(转)You might not need jQuery
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.
AJAX
Post
jQuery
$.ajax({
type: 'POST',
url: '/my/url',
data: data
});
IE8+
var request = new XMLHttpRequest();
request.open('POST', '/my/url', true);
request.send(data);
JSON
jQuery
$.getJSON('/my/url', function(data) {
});
IE8+
request = new XMLHttpRequest;
request.open('GET', '/my/url', true);
request.onreadystatechange = function() {
if (this.readyState === 4){
if (this.status >= 200 && this.status < 400){
// Success!
data = JSON.parse(this.responseText);
} else {
// Error :(
}
}
request.send();
request = null;
IE9+
request = new XMLHttpRequest;
request.open('GET', '/my/url', true);
request.onload = function() {
if (request.status >= 200 && request.status < 400){
// Success!
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+
request = new XMLHttpRequest
request.open('GET', '/my/url', true)
request.onload = function() {
if (this.status >= 200 && this.status < 400){
// Success!
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()
Request
jQuery
$.ajax({
type: 'GET',
url: '/my/url',
success: function(resp) {
},
error: function() {
}
});
IE8+
request = new XMLHttpRequest;
request.open('GET', '/my/url', true);
request.onreadystatechange = function() {
if (this.readyState === 4){
if (this.status >= 200 && this.status < 400){
// Success!
resp = this.responseText;
} else {
// Error :(
}
}
}
request.send();
request = null;
IE9+
request = new XMLHttpRequest
request.open('GET', '/my/url', true)
request.onload = function() {
if (request.status >= 200 && request.status < 400){
// Success!
resp = 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+
request = new XMLHttpRequest
request.open('GET', '/my/url', true)
request.onload = function() {
if (this.status >= 200 && this.status < 400){
// Success!
resp = 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()
Effects
Fade In
jQuery
$(el).fadeIn();
IE8+
function fadeIn(el) {
var opacity = 0;
el.style.opacity = 0;
el.style.filter = '';
var last = +new Date();
var tick = function() {
opacity += (new Date() - last) / 400;
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) {
el.style.opacity = 0;
var last = +new Date();
var tick = function() {
el.style.opacity = +el.style.opacity + (new Date() - last) / 400;
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;
}
Elements
Add Class
jQuery
$(el).addClass(className);
IE8+
if (el.classList)
el.classList.add(className);
else
el.className += ' ' + className;
IE10+
el.classList.add(className);
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
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){
});
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);
Finding Elements
jQuery
$('.my #awesome selector');
IE8+
document.querySelectorAll('.my #awesome selector');
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]
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);
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 {
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)(selector);
};
matches(el, '.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
Outer Height
jQuery
$(el).outerHeight()
IE8+
function outerHeight(el, includeMargin){
var height = el.offsetHeight;
if(includeMargin){
var style = el.currentStyle || getComputedStyle(el);
height += parseInt(style.marginTop) + parseInt(style.marginBottom);
}
return height;
}
outerHeight(el, true);
IE9+
function outerHeight(el, includeMargin){
var height = el.offsetHeight;
if(includeMargin){
var style = getComputedStyle(el);
height += parseInt(style.marginTop) + parseInt(style.marginBottom);
}
return height;
}
outerHeight(el, true);
Outer Width
jQuery
$(el).outerWidth()
IE8+
function outerWidth(el, includeMargin){
var height = el.offsetWidth;
if(includeMargin){
var style = el.currentStyle || getComputedStyle(el);
height += parseInt(style.marginLeft) + parseInt(style.marginRight);
}
return height;
}
outerWidth(el, true);
IE9+
function outerWidth(el, includeMargin){
var height = el.offsetWidth;
if(includeMargin){
var style = getComputedStyle(el);
height += parseInt(style.marginLeft) + parseInt(style.marginRight);
}
return height;
}
outerWidth(el, true);
Prev
jQuery
$(el).prev();
IE8+
// prevSibling can include text nodes
function prevElementSibling(el) {
do { el = el.prevSibling; } while ( el && el.nodeType !== 1 );
return el;
}
el.prevElementSibling || prevElementSibling(el);
IE9+
el.prevElementSibling
Remove Class
jQuery
$(el).removeClass(className);
IE8+
if (el.classList)
el.classList.remove(className);
else
el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
IE10+
el.classList.remove(className);
Set Style
jQuery
$(el).css('border-width', '20px');
IE8+
// Use a class if possible
el.style.borderWidth = '20px';
Setting Text
jQuery
$(el).text(string);
IE8+
if (el.textContent !== undefined)
el.textContent = string;
else
el.innerText = string;
IE9+
el.textContent = string;
Siblings
jQuery
$(el).siblings();
IE8+
var siblings = Array.prototype.slice.call(el.parentNode.children);
for (var i = siblings.length; i--;) {
if (siblings[i] === el) {
siblings.splice(i, 1);
break;
}
}
IE9+
Array.prototype.filter.call(el.parentNode.children, function(child){
return 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)
Events
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);
IE8+
function addEventListener(el, eventName, handler) {
if (el.addEventListener) {
el.addEventListener(eventName, handler);
} else {
el.attachEvent('on' + eventName, handler);
}
}
addEventListener(el, eventName, handler);
IE9+
el.addEventListener(eventName, eventHandler);
Ready
jQuery
$(document).ready(function(){
});
IE8+
function ready(fn) {
if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', fn);
} else {
document.attachEvent('onreadystatechange', function() {
if (document.readyState === 'interactive')
fn();
});
}
}
IE9+
document.addEventListener('DOMContentLoaded', function(){
});
Trigger Custom
Alternatives:
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) {
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);
Trigger Native
jQuery
$(el).trigger('change');
IE8+
if (document.createEvent) {
var event = document.createEvent('HTMLEvents');
event.initEvent('change', true, false);
el.dispatchEvent(event);
} else {
el.fireEvent('onchange');
}
IE9+
// For a full list of event types: https://developer.mozilla.org/en-US/docs/Web/API/document.createEvent
event = document.createEvent('HTMLEvents');
event.initEvent('change', true, false);
el.dispatchEvent(event);
Utils
Array Each
jQuery
$.each(array, function(i, item){
});
IE8+
function forEach(array, fn) {
for (i = 0; i < array.length; i++)
fn(array[i], i);
}
forEach(array, function(item, i){
});
IE9+
array.forEach(function(item, i){
});
Deep Extend
jQuery
$.extend(true, {}, objA, objB);
IE8+
var deepExtend = function(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)) {
if (typeof obj[key] === 'object')
deepExtend(out[key], obj[key]);
else
out[key] = obj[key];
}
}
}
return out;
};
deepExtend({}, objA, objB);
Extend
Alternatives:
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);
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);
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){
})
Parse Html
jQuery
$.parseHTML(htmlString)
IE8+
var parseHTML = function(str) {
var el = document.createElement('div')
el.innerHTML = str
return el.children
}
parseHTML(htmlString)
IE9+
var parseHTML = function(str) {
var tmp = document.implementation.createHTMLDocument()
tmp.body.innerHTML = str
return tmp.body.children
}
parseHTML(htmlString)
Made by @adamfschwartz and @zackbloom at HubSpot.