jQuery 和它的相关插件都是很强大的,使用它们让我们的应用开发变得简单。如果你正在开发另一个库,请花点时间思考以下,你是否真的需要依赖jQuery。如果你的应用仅针对更现代的浏览器,你可能不需要做过多的浏览器适配。
至少,你要知道 jQuery 为你做了些什么,和没有为你做些什么。一些开发者认为 jQuery 让我们从浏览器兼容中得以解脱,事实上,IE8之后,浏览器自身已经做的很好了。
$.getJSON('/my/url', function (data) {});
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;
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();
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();
const data = await (await fetch('/my/url')).json();
$('#some.selector').load('/path/to/template.html');
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');
$.ajax({
type: 'POST',
url: '/my/url',
data: data,
});
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);
$.ajax({
type: 'GET',
url: '/my/url',
success: function (resp) {},
error: function () {},
});
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();
}
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();
}
$(el).fadeIn();
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);
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);
el.classList.add('show');
el.classList.remove('hide');
.show {
transition: opacity 400ms;
}
.hide {
opacity: 0;
}
$(el).fadeOut();
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);
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);
el.classList.add('hide');
el.classList.remove('show');
.show {
opacity: 1;
}
.hide {
opacity: 0;
transition: opacity 400ms;
}
$(el).toggle();
function toggle(el) {
if (el.style.display == 'none') {
el.style.display = '';
} else {
e.style.display = 'none';
}
}
$(el).addClass(className);
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;
}
}
el.classList.add(className);
$(el).children();
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]);
}
el.children;
$(el).closest(sel);
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);
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);
el.closest(sel);
$('<div>Hello World!</div>');
function generateElements(html) {
var div = document.createElement('div');
div.innerHTML = html;
if (div.children.length === 0) {
return null;
}
if (div.children.length === 1) {
return div.firstChild;
} else {
return div.children;
}
}
generateElements('<div>Hello World!</div>');
$(selector).each(function (i, el) {});
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) {});
var elements = document.querySelectorAll(selector);
Array.prototype.forEach.call(elements, function (el, i) {});
$(selector).filter(filterFn);
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);
Array.prototype.filter.call(document.querySelectorAll(selector), filterFn);
$(el).height();
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);
parseFloat(getComputedStyle(el, null).height.replace('px', ''));
$(el).css(ruleName);
// 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
getComputedStyle(el)[ruleName];
$(el).width();
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);
parseFloat(getComputedStyle(el, null).width.replace('px', ''));
$(el).hasClass(className);
if (el.classList) el.classList.contains(className);
else new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className);
el.classList.contains(className);
$(el).index();
function index(el) {
if (!el) return -1;
var i = 0;
while (el) {
el = el.previousSibling;
if (el && el.nodeType === 1) i++;
}
return i;
}
function index(el) {
if (!el) return -1;
var i = 0;
while ((el = el.previousElementSibling)) {
i++;
}
return i;
}
$(el).is('.my-class');
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');
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');
$(el).next();
// nextSibling can include text nodes
function nextElementSibling(el) {
do {
el = el.nextSibling;
} while (el && el.nodeType !== 1);
return el;
}
el.nextElementSibling || nextElementSibling(el);
el.nextElementSibling;
$(el).offset();
var rect = el.getBoundingClientRect();
{
top: rect.top + document.body.scrollTop,
left: rect.left + document.body.scrollLeft,
};
function offset(el) {
box = el.getBoundingClientRect();
docElem = document.documentElement;
return {
top: box.top + window.pageYOffset - docElem.clientTop,
left: box.left + window.pageXOffset - docElem.clientLeft,
};
}
$(el).outerHeight(true);
function outerHeight(el) {
var height = el.offsetHeight;
var style = el.currentStyle || getComputedStyle(el);
height += parseInt(style.marginTop) + parseInt(style.marginBottom);
return height;
}
outerHeight(el);
function outerHeight(el) {
var height = el.offsetHeight;
var style = getComputedStyle(el);
height += parseInt(style.marginTop) + parseInt(style.marginBottom);
return height;
}
outerHeight(el);
$(el).outerWidth(true);
function outerWidth(el) {
var width = el.offsetWidth;
var style = el.currentStyle || getComputedStyle(el);
width += parseInt(style.marginLeft) + parseInt(style.marginRight);
return width;
}
outerWidth(el);
function outerWidth(el) {
var width = el.offsetWidth;
var style = getComputedStyle(el);
width += parseInt(style.marginLeft) + parseInt(style.marginRight);
return width;
}
outerWidth(el);
$(el).position();
function offset(el) {
box = el.getBoundingClientRect();
docElem = document.documentElement;
return {
top: box.top + (window.pageYOffset || docElem.scrollTop),
left: box.left + (window.pageXOffset || docElem.scrollLeft),
};
}
var offset = $(el).offset();
{
top: offset.top - document.body.scrollTop,
left: offset.left - document.body.scrollLeft,
};
el.getBoundingClientRect();
$(el).prev();
// prevSibling can include text nodes
function previousElementSibling(el) {
do {
el = el.previousSibling;
} while (el && el.nodeType !== 1);
return el;
}
el.previousElementSibling || previousElementSibling(el);
el.previousElementSibling;
$(el).removeClass(className);
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), '');
}
}
}
el.classList.remove(className);
$(el).height(val);
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);
$(el).css('border-width', '20px');
// Use a class if possible
el.style.borderWidth = '20px';
$(el).text(string);
if (el.textContent !== undefined) el.textContent = string;
else el.innerText = string;
el.textContent = string;
$(el).width(val);
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);
$(el).siblings();
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);
var siblings = function (el) {
if (el.parentNode === null) return [];
return Array.prototype.filter.call(el.parentNode.children, function (child) {
return child !== el;
});
};
siblings(el);
$(el).toggleClass(className);
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(' ');
}
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(' ');
}
el.classList.toggle(className);
$(el).click(function () {});
var onClick = function (element, handler) {
if (element.addEventListener) {
element.addEventListener('click', handler, false);
} else {
element.attachEvent('onclick', handler);
}
};
onClick(el, function () {});
el.addEventListener('click', function () {}, false);
$(document).on(eventName, elementSelector, handler);
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
);
$(el).off(eventName, eventHandler);
function removeEventListener(el, eventName, handler) {
if (el.removeEventListener) el.removeEventListener(eventName, handler);
else el.detachEvent('on' + eventName, handler);
}
removeEventListener(el, eventName, handler);
el.removeEventListener(eventName, eventHandler);
$(el).on(eventName, eventHandler);
// Or when you want to delegate event handling
$(el).on(eventName, selector, eventHandler);
function addEventListener(el, eventName, handler) {
if (el.addEventListener) {
el.addEventListener(eventName, handler);
} else {
el.attachEvent('on' + eventName, function () {
handler.call(el);
});
}
}
addEventListener(el, eventName, handler);
function addEventListener(el, eventName, eventHandler, selector) {
if (selector) {
el.addEventListener(eventName, function (e) {
if (e.target && e.target.matches(selector)) {
eventHandler(e);
}
});
} else {
el.addEventListener(eventName, eventHandler);
}
}
addEventListener(el, eventName, eventHandler);
// Or when you want to delegate event handling
addEventListener(el, eventName, eventHandler, selector);
$(document).ready(function () {});
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();
});
}
}
function ready(fn) {
if (document.readyState != 'loading') {
fn();
} else {
document.addEventListener('DOMContentLoaded', fn);
}
}
$(el).trigger('my-event', {some: 'data'});
// Custom events are not natively supported, so you have to hijack a random
// event.
//
// Just use jQuery.
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);
$(el).trigger('change');
if (document.createEvent) {
var event = document.createEvent('HTMLEvents');
event.initEvent('change', true, false);
el.dispatchEvent(event);
} else {
el.fireEvent('onchange');
}
// For a full list of event types: https://developer.mozilla.org/en-US/docs/Web/API/document.createEvent
var event = document.createEvent('HTMLEvents');
event.initEvent('change', true, false);
el.dispatchEvent(event);
$.each(array, function (i, item) {});
function forEach(array, fn) {
for (var i = 0; i < array.length; i++) fn(array[i], i);
}
forEach(array, function (item, i) {});
array.forEach(function (item, i) {});
$.extend(true, {}, objA, objB);
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' && obj[key] !== null) {
if (obj[key] instanceof Array) out[key] = obj[key].slice(0);
else out[key] = deepExtend(out[key], obj[key]);
} else out[key] = obj[key];
}
}
}
return out;
};
deepExtend({}, objA, objB);
$.extend({}, objA, objB);
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);
$.inArray(item, array);
function indexOf(array, item) {
for (var i = 0; i < array.length; i++) {
if (array[i] === item) return i;
}
return -1;
}
indexOf(array, item);
array.indexOf(item);
$.isArray(arr);
isArray =
Array.isArray ||
function (arr) {
return Object.prototype.toString.call(arr) == '[object Array]';
};
isArray(arr);
Array.isArray(arr);
$.isNumeric(val);
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);
$.map(array, function (value, index) {});
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) {});
array.map(function (value, index) {});
$.each(obj, function (key, value) {});
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) {});
$.parseHTML(htmlString);
var parseHTML = function (str) {
var el = document.createElement('div');
el.innerHTML = str;
return el.childNodes;
};
parseHTML(htmlString);
var parseHTML = function (str) {
var tmp = document.implementation.createHTMLDocument('');
tmp.body.innerHTML = str;
return Array.prototype.slice.call(tmp.body.childNodes);
};
parseHTML(htmlString);
$(els).slice(begin, end);
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);
els.slice(begin, end);
$(selector).toArray();
function toArray(selector) {
var array = [];
var elements = document.querySelectorAll(selector);
for (var i = 0; i < elements.length; i++) array.push(elements[i]);
return array;
}
$.type(obj);
Object.prototype.toString
.call(obj)
.replace(/^\[object (.+)\]$/, '$1')
.toLowerCase();