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 ids 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.