Last active
August 29, 2015 14:03
-
-
Save sehrgut/77233df47b17a3bc9257 to your computer and use it in GitHub Desktop.
jQuery plugin to find elements based on computed CSS styles
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
jquery.withStyles.js - jQuery plugin to find elements based on computed CSS styles | |
Copyright (C) 2014 Keith Beckman | |
Released under the GPLv3 | |
## Usage | |
* Returns collection of all `a` tags with computed styles matching the CSS declaration | |
* `$('a:withStyles("font-style: bold; color: #FFFFFF;")')` | |
* `$('a').filter(':withStyles("font-style: bold; color: #FFFFFF;")')` | |
* `$('a').withStyles("font-style: bold; color: #FFFFFF;")` | |
* Returns a collection of all `a` tags with computed styles matching the provided map of CSS properties and values | |
* `$('a').withStyles({ fontStyle: "bold", color: "#FFFFFF" })` | |
* `$('a').withStyles({ "font-style": "bold", "color": "#FFFFFF" })` | |
* Returns `boolean` indicating if the selected element matches the provided styles | |
* `$('a').first().hasStyles("font-style: bold; color: #FFFFFF;")` | |
* `$('a').first().hasStyles({ fontStyle: "bold", color: "#FFFFFF" })` | |
* `$('a').first().hasStyles({ "font-style": "bold", "color": "#FFFFFF" })` | |
## Notes | |
This may not function in all older browsers. It depends on the existence of a | |
DOM Level 2-compliant implementation of `CSSStyleDeclaration` to walk explicit | |
CSS properties of a dummy DOM element. | |
Using the browser-native parser is necessary to permit matching of values which | |
have multiple semantically-equivalent representations, but which may be handled | |
differently by different browsers (such as colour literals). | |
## TODO | |
* Allow determination of style of text nodes (nodeType === 3) to avoid exceptions | |
when working on the results of jQuery.contents(). Probably take the direct | |
parent's style? (Or a setting: `ignoreTextNodes`, default to `false`.) | |
*/ | |
(function ($) { | |
function isString (o) { | |
return (typeof o === 'string' || o instanceof String); | |
} | |
function getExplicitStyles (el) { | |
var out = {}; | |
for (var i=0, n=el.style.length; i<n; i++) { | |
var prop = el.style[i]; | |
out[prop] = el.style[prop]; | |
} | |
return out; | |
} | |
var parseCssDeclaration = (function () { | |
var $span = $('<span />'); | |
return function (css) { | |
return getExplicitStyles($span.attr('style', css)[0]); | |
}; | |
})(); | |
var compareStyle = (function () { | |
var jq = $([1]); | |
return function (el, props) { | |
jq[0] = el; | |
for (var prop in props) | |
if (jq.css(prop) !== props[prop]) | |
return false; | |
return true; | |
}; | |
})(); | |
$.fn.hasStyles = function (styles) { | |
var props = isString(styles) ? parseCssDeclaration(styles) : styles; | |
return this.length === 1 && compareStyle(el, props); | |
}; | |
$.fn.withStyles = function (styles) { | |
var props = isString(styles) ? parseCssDeclaration(styles) : styles; | |
return this.filter(function (i, el) { | |
return compareStyle(el, props); | |
}); | |
}; | |
var Sizzle = $.find; | |
Sizzle.selectors.pseudos['withStyles'] = Sizzle.selectors.createPseudo ? | |
Sizzle.selectors.createPseudo(function (css) { | |
var props = parseCssDeclaration(css); | |
return function (el) { | |
return compareStyle(el, props); | |
}; | |
}) : | |
function (el, i, meta, stack) { | |
var props = parseCssDeclaration(meta[3]); | |
return compareStyle(el, props); | |
}; | |
})(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment