Skip to content

Instantly share code, notes, and snippets.

@bryanerayner
Forked from RubaXa/jquery.classList.js
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bryanerayner/8be2ff8353bf33a0f3ec to your computer and use it in GitHub Desktop.
Save bryanerayner/8be2ff8353bf33a0f3ec to your computer and use it in GitHub Desktop.
Change jQuery to use the more performant classList over string concatenation methods, when ClassList is available
/**
* jQuery extension, add support `classList`.
*
* @author RubaXa <trash@rubaxa.org>, bryanerayner <bryan@bryanerayner.ca>
* @license MIT
*/
(function ($) {
var
_rspace = /\s+/
, _$cache = $('<div/>')
, _div = _$cache[0]
, _classList = _div.classList
, _supportsArgs
;
var _each = function ($el, method, callback) {
$el.each(function (i) {
_$cache[0] = this;
_$cache[method](callback.call(this, i, _$cache.attr('class')));
});
}
var _factory = function (method) {
return function (value) {
var typeOf = typeof value, i = this.length;
if ('string' === typeOf) {
value = $.trim(value);
if ("" !== value) {
value = value.split(_rspace);
var j, n = value.length, list;
while (i--) {
list = this[i].classList;
if (1 === n) {
list[method](value[0]);
}
else if (_supportsArgs) {
list[method].apply(list, value);
}
else {
for (j = 0; j < n; j++) {
list[method](value[j]);
}
}
}
}
}
else if ((void 0 === value) && ('remove' === method)) {
while (i--) {
this[i].className = '';
}
}
else if ('function' === typeOf) {
_each(this, method + 'Class', value);
}
return this;
}
}
if (_classList) {
_classList.add('-a', 'b-');
_supportsArgs = /-a/.test(_div.className) && /b-/.test(_div.className);
/**
* Has class
*
* @param {string} className
* @returns {boolean}
*/
$.fn.hasClass = function (className) {
className = $.trim(className);
var splitClassNames = className.split(_rspace);
var s = splitClassNames.length;
var i = this.length;
var numContained = 0;
while (i--) {
numContained = 0;
for (var q = 0; q < s; q++) {
if (this[i].classList.contains(splitClassNames[q])) {
numContained++;
}
}
if (numContained === s)
{
return true;
}
}
return false;
};
/**
* Add class
*
* @param {string|function} value
* @returns {jQuery}
*/
$.fn.addClass = _factory('add');
/**
* Remove class
*
* @param {string|function} value
* @returns {jQuery}
*/
$.fn.removeClass = _factory('remove');
}
// Cleanup
_$cache[0] = _div = _classList = null;
})(jQuery);
@bryanerayner
Copy link
Author

Revised the file to properly declare nested functions (they should be variables) and support cases where 'hasClass' is queried by user input with a space separated string

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment