Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
327 views
in Technique[技术] by (71.8m points)

javascript - Find HTML based on partial attribute

Is there a way with javascript (particularly jQuery) to find an element based on a partial attribute name?

I am not looking for any of the selectors that find partial attribute values as referenced in these links:

but more something along the lines of

<div data-api-src="some value"></div>
<div data-api-myattr="foobar"></div>

and

$("[^data-api]").doSomething()

to find any element that has an attribute that starts with "data-api".

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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/


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.9k users

...