views:

389

answers:

4

What I am attempting to do is see if a jQuery object (or even DOM element for that matter) contains a particular class using the same selectors as the Sizzle engine.

jQuery publicly exposes Sizzle with the following:

jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors;
jQuery.expr[":"] = jQuery.expr.filters;
jQuery.unique = Sizzle.uniqueSort;

I can successfully use the find method to determine that a particular DOM element has a class matching my selector but I cannot seem to find a way to get access to the name of the selector that matched.

EXAMPLE (NOT WORKING AS INTENDED)

$.fn.extend({
    getMatchingClass: function(selector) {
        return this.each(function() {
            var match = jQuery.find.matches('*[class'+selector+']', [this]);
                    // I would like to return the matching class's FULL NAME,
                    // i.e. lightbox_RESTOFCLASS
            alert(match[0]);
        });
    }
});

var class = $('#lightbox').getMatchingClass('^="lightbox_"');

Is it possible to use Sizzle to return the class name which matched my selector?

A: 

Now that I better understand your question, have you tried using native Sizzle selectors to do what you're trying to do?

The contains word selector should do what you're looking for:

$('#lightbox').find("[class~='lightbox']");

Once you have the element, you can then easily get the class name by calling attr(...):

var className = $('#lightbox').find("[class~='lightbox_']").attr('class');

This will only give you the entire class attribute, not the individual classes for the element. You'd have to split(' ') the className to get the individual classes and find a matching class.

function getSimilarClass(className, searchString) {
    var classes = className.split(' ');
    for(var i = 0; i < classes.length; i++) {
        if (classes[i].indexOf(searchString) != -1) {
            return classes[i];
        }
    }
    return null;
}
var className = $('#lightbox').find("[class~='lightbox_']").attr('class');
var match = getSimilarClass(className, "lightbox_");

This process has flaws however, since there could be multiple tags with similar classes, which this won't account for, and individual tags could potentially have several classes with similar names.

Dan Herbert
@Dan - I would like to find the particular classes *full name* matching a Sizzle selector. For example: If you only know the beginning part of the class name and you would like to find the full name of that class.
cballou
A: 

You could use the attr( name ) function of the jQuery library ..

You could modify your original function to take as parameters both the selector and the attribute to apply it to .. this way you can query the results for the specified attribute value.

$.fn.extend({
    getMatchingClass: function(attribute, selector) {
        return this.each(function() {
            var match = jQuery.find.matches('*['+attribute+selector+']', [this]);
                    // I would like to return the matching class's FULL NAME,
                    // i.e. lightbox_RESTOFCLASS
            alert( $(match[0]).attr(attribute) );
        });
    }
});

Keep in mind that the selector might match more than one classes. Which result would you want then? a list of all matches ? or just the first (as the alerted value in the example)

[edit] this does not take into account though the case where you have more than one class on an item ..

Gaby
A: 

of course your selector doesnt have to be "li" it can be whatever criteria you do know about the items you want to select. but to get the entire class attribute, just use the .attr("class") selector. like this

$(document).ready(function(){
    $("li").each(function (i) {
        var class = $(this).attr("class");
            alert(class);
    });
});
Jon Briccetti
@Jon - I'm only looking for a particular class match, not the entirety of the class attribute.
cballou
A: 

I've come up with a non-sizzle solution using a subset of selectors (^=, $=, *=, and =) which is fully working. A Sizzle solution would have been nice, however. This should at least demonstrate what the intended functionality of the plugin should do.

$.fn.getMatchingClass = function(selector) {
    var regex, class, tmp, $this;
    tmp = $(this)[0].className;
    class = selector;
    class = class.replace(/(\^|\*|\$)?=/i, '');
    class = class.replace(/\"/g, '');
    if (selector.indexOf('$=') != -1) {
        regex = new RegExp('[\\s]+' + class + '$', 'i');
    } else if (selector.indexOf('^=') != -1) {
        regex = new RegExp('^' + class + '[\\s]+', 'i');
    } else if (selector.indexOf('*=') != -1) {
        regex = new RegExp('[a-zA-z0-9_\\-]*' + class + '[a-zA-z0-9_\\-]*', 'gi');
    } else if (selector.indexOf('=') != -1) {
        regex = new RegExp('^' + class + '$', 'i');
    } else return false;
    return tmp.match(regex);
}

var class = $('#myID').getMatchingClass('*="lightbox"');
var class2 = $('#myID').getMatchingClass('^=lightbox');
var class3 = $('#myID').getMatchingClass('="lightbox"');
var class4 = $('#myID').getMatchingClass('$=lightbox');
alert(class);
alert(class2);
alert(class3);
alert(class4);
cballou