This is quite old, but hear me out on this one.
$.fn.extend({
hasClasses: function (selectors) {
// Setup
const _id = $(this).attr('id'); // Preserve existing id
const uuid = generateUUID(); // Create new id for query
$(this).attr('id', uuid); // Apply new id to element
// Query to find if element has any of the classes
const res = selectors.some(cls => !!$(`${uuid}.${cls}`).length);
// Rollback on id
if (!_id) $(this).removeAttr("id"); // No Id to begin with
else $(this).attr('id', _id); // Preserve old id
// Done
return res;
}
})
Instead of trying to find a match between one of the classes in selectors
and one of the element's classes we simply apply a temporary id
(uuid) to the element and query to find if there exists some element with that temporary id
and any of the classes listed in selectors
.
This inspired by Kalel Wade's and Simon Arnold's solution but with a minor improvement to performance (benchmarked on jsbench.me).
Note
JSBENCH doesn't allow saving over a limit of a certain amount of characters or words. I had some trouble with the async fetching of random words, so you can get random words manually and use the bench that way.
EDIT:
I just noticed that for my implementation of this I am relying on the id
with async calls. I might cause an issue if I need to query the element by id the same time that hasClasses
changes the id
.
To circumvent this we can just add a unique uuid
attribute (literally just the uuid
).
Here is the correction:
$.fn.extend({
hasClasses: function (selectors) {
// Setup
const uuid = generateUUID(); // Create new uuid to query later
$(this).attr(uuid, ""); // Apply uuid to element for query
// Query to find if element has any of the classes
const res = selectors.some(cls => !!$(`[${uuid}].${cls}`).length);
// Remove the uuid attribute
$(this).removeAttr(uuid);
// Done
return res;
}
})
We could still use an the elements' id
if it has one instead of adding an attribute
.
I'm not sure if querying id
s is faster or not. I referenced this, but by the looks of it there isn't much of a hit with modern browsers. Could still implement using the id
if it exists instead of an attribute
.