Reputation: 57129
If I want to select every image which it's alt is Home for example, I can do something like this:
$("img[alt='Home']")
But how can I select every elements which their width
CSS property is 750px for example in a single selector?
EDIT: If there is no such selector, is there any plugin, or any plans to do it in the next jQuery versions?
Upvotes: 15
Views: 19590
Reputation: 752
This is an old one, but thanks to Jonathan del Strother's answer, it got me thinking on how to round this out a bit more:
(function($){
// Add commonly used regex to the jQuery object
var regex = {
digits: /^(-?\d+(?:\.\d+)?)([a-zA-Z]+)?$/
,expr: /^([\w-]+)\s*([:=<>])\s*([\w-\.]+(?:\([^\)]+\))?)$/
};
// Create a custom jQuery function that allows a bit more useful CSS extraction
$.fn.extend({
cssExtract: function(cssAttr) {
var val = {prop:this.css(cssAttr)};
if (typeof val.prop === "string") {
var match = regex.digits.exec(val.prop);
if (match) {
val.int = Number(match[1]);
val.metric = match[2] || "px"
}
}
return val;
}
});
// Create the custom style selector
$.find.selectors[":"].style = function(el, pos, match) {
var search = regex.expr.exec(match[3]);
if (search) {
var style = search[1]
,operator = search[2]
,val = search[3]
,target = $(el).cssExtract(style)
,compare = (function(result){
if (result) {
return {
int: Number(result[1])
,metric: result[2] || "px"
};
}
return null;
})(regex.digits.exec(val));
if (
target.metric
&& compare && compare.metric
&& target.metric === compare.metric
) {
if (operator === "=" || operator === ":") {
return target.int === compare.int;
} else if (operator === "<") {
return target.int < compare.int;
} else if (operator === ">") {
return target.int > compare.int;
}
} else if (target.prop && (operator === "=" || operator === ":")) {
return target.prop === val;
}
}
return false;
};
})(jQuery);
You should now be able to easily query with the custom style
selector as follows:
$("div:style(height=57)")
At the time of this answer - should return the top div elements of Stack Overflow (this page).
Something like this will even work:
$("h3:style(color:rgb(106, 115, 124))")
Try adding the code in the developer tools in your browser. I tested it in Chrome. Haven't tested it in others. I also didn't put too much work into researching other pre-existing libraries/plugin's out there.
Upvotes: 1
Reputation: 66
I had a similar issue. Ended up writing a plugin to select elements based on their computed style.
https://github.com/MikeCostello/query-declaration
jQuery
$(":style({ width: 750px})")
Upvotes: 0
Reputation: 342665
var $images = $("img").filter(function() {
return $(this).css('width') == '750px';
});
EDIT: There is no plugin I am aware of, or any plans to include such specific functionality. You can easily pluginify it yourself, such as (untested):
$.fn.filterByWidth = function(width) {
var $images = $("img").filter(function() {
return $(this).css('width') == width;
});
return $images;
};
Usage:
$images = $('#div img').filterByWidth('750px');
$images = $('#div img').filterByWidth('50%');
...etc...
Upvotes: 15
Reputation: 2572
Not necessarily a great idea, but you could add a new Sizzle selector for it :
$.expr[':'].width = function(elem, pos, match) {
return $(elem).width() == parseInt(match[3]);
}
which you could then use like so:
$('div:width(970)')
That's going to be horrifically slow, though, so you'd want to narrow down on the number of elements you're comparing with something like :
$('#navbar>div:width(970)')
to only select those divs that are direct descendants of the navbar, which also have a width of 970px.
Upvotes: 17
Reputation: 88806
I have no idea if this will work, but...:
${"[style*=width: 750px]")
However, you might be better off using a class to control the width, then modifying the width of all instances of that class... or changing to a different class:
$(".classname").removeClass("classname").addClass("otherclassname");
Upvotes: 5