开发者

Writing jQuery selector case-insensitive version

开发者 https://www.devze.com 2023-01-20 15:18 出处:网络
I\'m using following line and I would like to make it case-insensitive: var matches = $(this).find(\'div > span > div#id_to_find[attributeName ^= \"filter\"]\');

I'm using following line and I would like to make it case-insensitive:

var matches = $(this).find('div > span > div#id_to_find[attributeName ^= "filter"]');
if (matches.length > 0) {
}

My question is that how can I make the selector ^= to be cas开发者_运维百科e-insensitive? Maybe changing to filter and then some regexp?


To do a case-insensitive attribute selection, you need to write a custom selector function.

$.expr[':'].iAttrStart = function(obj, params, meta, stack) {
    var opts = meta[3].match(/(.*)\s*,\s*(.*)/);
    return (opts[1] in obj) && (obj[opts[1]].toLowerCase().indexOf(opts[2].toLowerCase()) === 0);
};

You can use this like this:

$('input:iAttrStart(type, r)')

This will match any input elements whose type attribute begins with R or r (so it would match RADIO, radio, RESET or reset). This is a pretty silly example, but it should do what you need.


Re the comment that the function is hard to understand, I'll explain it a little.

$.expr[':'].iAttrStart = function(obj, params, meta, stack) {

This is the standard signature for creating custom selectors.

var opts = meta[3].match(/(.*)\s*,\s*(.*)/);

meta is an array of details about the call. meta[3] is the string passed as the parameter. In my example, this is type, r. The regex matches type and r separately.

return (opts[1] in obj) && (obj[opts[1]].toLowerCase().indexOf(opts[2].toLowerCase()) === 0);

Return if both these are true:

  1. The requested attribute exists on this object (opts[1] in obj)
  2. The search term (changed to lower-case) is found at the very beginning of the element's attribute value, also changed to lower case.

I could have made this easier to read using jQuery syntax rather than native JS syntax, but that would have meant reduced performance.


Here you can see:

http://www.ericmmartin.com/creating-a-custom-jquery-selector/

What you have to do is to create a custom jquery selector:

jQuery.extend(jQuery.expr[':'], {
    exactIgnoreCase: "(a.textContent||a.innerText||jQuery(a).text()||'').toLowerCase() == (m[3]).toLowerCase()"
});

And then just use it:

$("#detail select.fields option:exactIgnoreCase(" + q.val() + "):first");


There's a slight problem when using lonesomeday's answer.

To reproduce the error, try this: HTML tag on page is a common Facebook meta tag:

<meta content="Title of og tag" property="og:title" />

Selector:

$('meta:attrCaseInsensitive(property, og:site_name)')

This will not work. The reason is because when the selector code gets to the statement (opts[1] in obj) it will execute ("property" in obj) which returns false. (I don't know why)

To fix this problem, I just changed the last line to use jQuery's attr() method

$.expr[':'].iAttrStart = function(obj, params, meta, stack) {
    var opts = meta[3].match(/(.*)\s*,\s*(.*)/);
    return (undefined != $(obj).attr(opts[1])) && (obj[opts[1]].toLowerCase().indexOf(opts[2].toLowerCase()) === 0)
};
0

精彩评论

暂无评论...
验证码 换一张
取 消