Find HTML based on partial attribute

This uses .filter() to limit the candidates to those that has data-api-* attributes. Probably not the most efficient approach, but usable if you can first narrow down the search with a relevant selector.

$("div").filter(function() {
    var attrs = this.attributes;
    for (var i = 0; i < attrs.length; i++) {
        if (attrs[i].nodeName.indexOf('data-api-') === 0) return true;       
    };
    return false;
}).css('color', 'red');

Demo: http://jsfiddle.net/r3yPZ/2/


This can also be written as a selector. Here’s my novice attempt:

$.expr[':'].hasAttrWithPrefix = function(obj, idx, meta, stack) {
    for (var i = 0; i < obj.attributes.length; i++) {
        if (obj.attributes[i].nodeName.indexOf(meta[3]) === 0) return true;
    };
    return false;
};

Usage:

$('div:hasAttrWithPrefix(data-api-)').css('color', 'red');

Demo: http://jsfiddle.net/SuSpe/3/

This selector should work for pre-1.8 versions of jQuery. For 1.8 and beyond, some changes may be required. Here’s an attempt at a 1.8-compliant version:

$.expr[':'].hasAttrWithPrefix = $.expr.createPseudo(function(prefix) {
    return function(obj) {
        for (var i = 0; i < obj.attributes.length; i++) {
            if (obj.attributes[i].nodeName.indexOf(prefix) === 0) return true;
        };
        return false;
    };
});

Demo: http://jsfiddle.net/SuSpe/2/


For a more generic solution, here’s a selector that takes a regex pattern and selects elements with attributes that match that pattern:

$.expr[':'].hasAttr = $.expr.createPseudo(function(regex) {
    var re = new RegExp(regex);
    return function(obj) {
        var attrs = obj.attributes
        for (var i = 0; i < attrs.length; i++) {
            if (re.test(attrs[i].nodeName)) return true;
        };
        return false;
    };
});

For your example, something like this should work:

$('div:hasAttr(^data-api-.+$)').css('color', 'red');

Demo: http://jsfiddle.net/Jg5qH/1/

Leave a Comment