如何通过 javascript/jQuery 从 CSS 类中获取样式属性?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16965515/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get a style attribute from a CSS class by javascript/jQuery?
提问by robsonrosa
How can I access a property from a CSS class by jQuery? I have a CSS class like:
如何通过 jQuery 从 CSS 类访问属性?我有一个 CSS 类,如:
.highlight {
color: red;
}
And I need to do a color animation on an object:
我需要在一个对象上做一个彩色动画:
$(this).animate({
color: [color of highlight class]
}, 750);
So that I can change from red
to blue
(in the CSS) and my animation will work in accordance with my CSS.
这样我就可以从red
到blue
(在 CSS 中)更改,并且我的动画将按照我的 CSS 工作。
One approach would be to place an invisible element with the highlight
class and then get the color of the element to use in the animation, but I guess this is a very, very bad practice.
一种方法是在highlight
类中放置一个不可见的元素,然后获取要在动画中使用的元素的颜色,但我想这是一种非常非常糟糕的做法。
Any suggestions?
有什么建议?
回答by rlemon
I wrote a small function that traverses the stylesheets on the document looking for the matched selector, then style.
我写了一个小函数,它遍历文档上的样式表,寻找匹配的选择器,然后设置样式。
There is one caveat, this will only work for style sheets defined with a style tag, or external sheets from the same domain.
有一个警告,这仅适用于使用样式标签定义的样式表,或来自同一域的外部表。
If the sheet is known you can pass it in and save yourself from having to look in multiple sheets (faster and if you have colliding rules it's more exact).
如果工作表已知,您可以将其传入并避免自己查看多张工作表(更快,如果您有冲突规则,则更准确)。
I only tested on jsFiddle with some weak test cases, let me know if this works for you.
我只用一些弱测试用例在 jsFiddle 上进行了测试,让我知道这是否适合你。
function getStyleRuleValue(style, selector, sheet) {
var sheets = typeof sheet !== 'undefined' ? [sheet] : document.styleSheets;
for (var i = 0, l = sheets.length; i < l; i++) {
var sheet = sheets[i];
if( !sheet.cssRules ) { continue; }
for (var j = 0, k = sheet.cssRules.length; j < k; j++) {
var rule = sheet.cssRules[j];
if (rule.selectorText && rule.selectorText.split(',').indexOf(selector) !== -1) {
return rule.style[style];
}
}
}
return null;
}
example usage:
用法示例:
var color = getStyleRuleValue('color', '.foo'); // searches all sheets for the first .foo rule and returns the set color style.
var color = getStyleRuleValue('color', '.foo', document.styleSheets[2]);
edit:
编辑:
I neglected to take into consideration grouped rules. I changed the selector check to this:
我忽略了考虑分组规则。我将选择器检查更改为:
if (rule.selectorText.split(',').indexOf(selector) !== -1) {
now it will check if any of the selectors in a grouped rules matches.
现在它将检查分组规则中的任何选择器是否匹配。
回答by Naftali aka Neal
Since you are already using jQuery try using the jQuery-ui's function switchClass
which would allow you to animate to this new color.
由于您已经在使用 jQuery,请尝试使用 jQuery-ui 的函数switchClass
,它允许您为这种新颜色设置动画。
For example:
例如:
$('div').switchClass( "", "highlight", 1000 );
In case you do not want to include the wholeUI library here is the code they use:
如果您不想包含整个UI 库,这里是他们使用的代码:
switchClass: function( remove, add, speed, easing, callback) {
return $.effects.animateClass.call( this, {
add: add,
remove: remove
}, speed, easing, callback );
}
And the animateClass fn:
和 animateClass fn:
var classAnimationActions = [ "add", "remove", "toggle" ],
shorthandStyles = {
border: 1,
borderBottom: 1,
borderColor: 1,
borderLeft: 1,
borderRight: 1,
borderTop: 1,
borderWidth: 1,
margin: 1,
padding: 1
};
function styleDifference( oldStyle, newStyle ) {
var diff = {},
name, value;
for ( name in newStyle ) {
value = newStyle[ name ];
if ( oldStyle[ name ] !== value ) {
if ( !shorthandStyles[ name ] ) {
if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
diff[ name ] = value;
}
}
}
}
return diff;
}
function getElementStyles( elem ) {
var key, len,
style = elem.ownerDocument.defaultView ?
elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
elem.currentStyle,
styles = {};
if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
len = style.length;
while ( len-- ) {
key = style[ len ];
if ( typeof style[ key ] === "string" ) {
styles[ $.camelCase( key ) ] = style[ key ];
}
}
// support: Opera, IE <9
} else {
for ( key in style ) {
if ( typeof style[ key ] === "string" ) {
styles[ key ] = style[ key ];
}
}
}
return styles;
}
$.effects.animateClass = function( value, duration, easing, callback ) {
var o = $.speed( duration, easing, callback );
return this.queue( function() {
var animated = $( this ),
baseClass = animated.attr( "class" ) || "",
applyClassChange,
allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
// map the animated objects to store the original styles.
allAnimations = allAnimations.map(function() {
var el = $( this );
return {
el: el,
start: getElementStyles( this )
};
});
// apply class change
applyClassChange = function() {
$.each( classAnimationActions, function(i, action) {
if ( value[ action ] ) {
animated[ action + "Class" ]( value[ action ] );
}
});
};
applyClassChange();
// map all animated objects again - calculate new styles and diff
allAnimations = allAnimations.map(function() {
this.end = getElementStyles( this.el[ 0 ] );
this.diff = styleDifference( this.start, this.end );
return this;
});
// apply original class
animated.attr( "class", baseClass );
// map all animated objects again - this time collecting a promise
allAnimations = allAnimations.map(function() {
var styleInfo = this,
dfd = $.Deferred(),
opts = $.extend({}, o, {
queue: false,
complete: function() {
dfd.resolve( styleInfo );
}
});
this.el.animate( this.diff, opts );
return dfd.promise();
});
// once all animations have completed:
$.when.apply( $, allAnimations.get() ).done(function() {
// set the final class
applyClassChange();
// for each animated element,
// clear all css properties that were animated
$.each( arguments, function() {
var el = this.el;
$.each( this.diff, function(key) {
el.css( key, "" );
});
});
// this is guarnteed to be there if you use jQuery.speed()
// it also handles dequeuing the next anim...
o.complete.call( animated[ 0 ] );
});
});
};
Working fiddle with all the functions that are needed: http://jsfiddle.net/maniator/3C5ZQ/
处理所需的所有功能:http: //jsfiddle.net/maniator/3C5ZQ/
回答by Joe
How about this?
这个怎么样?
$('<span class="highlight"></span>').appendTo('body');
$(this).animate({
color: $('.highlight').css('color')
}, 750);
$('.highlight').remove();
It's kind of dirty but will give you an (empty) element to reference to get the CSS value for which you are looking.
这有点脏,但会给你一个(空)元素来引用以获得你正在寻找的 CSS 值。
UpdateHere is a decent solution from CSS parser/abstracter? How to convert stylesheet into object
更新这是来自CSS 解析器/抽象器的一个不错的解决方案?如何将样式表转换为对象
function findColorProperty(selector) {
rules = document.styleSheets[0].cssRules
for(i in rules) {
//if(rules[i].selectorText==selector)
//return rules[i].cssText; // Original
if(rules[i].selectorText == selector)
return rules[i].style.color; // Get color property specifically
}
return false;
}
Usage
用法
$(this).animate({
color: findColorProperty('.highlight')
}, 750);
Here is a fiddle http://jsfiddle.net/wzXDx/1/. I had to use styleSheets[1]
to get this to work in the fiddle due to the embedded nature of the environment.
这是一个小提琴http://jsfiddle.net/wzXDx/1/。styleSheets[1]
由于环境的嵌入特性,我不得不使用它来解决这个问题。
回答by Alex Char
The only solution that come to my mind is the following:
我想到的唯一解决方案如下:
//create an element with this class and append it to the DOM
var eleToGetColor = $('<div class="highlight" style="display: none;">').appendTo('body');
//get the color of the element
var color = eleToGetColor.css('color');
//completly remove the element from the DOM
eleToGetColor.remove();
$("div").animate({
//set the new color
color: color,
}, 1000);
.highlight {
color: red;
}
div {
width: 200px;
height: 100px;
color: blue;
font-size: 6em;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/themes/smoothness/jquery-ui.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/jquery-ui.min.js"></script>
<div>TEST</div>
回答by peter_jokumsen
Unfortunately I can't comment on this awesome answer, but found a case that isn't catered for (when CSS class is declared multiple times and the first declaration doesn't have the style you're looking for), made a jsFiddleto cater for it:
不幸的是,我不能在这真棒评论答案时,却发现没有照顾的情况下(当CSS类被多次声明和第一个声明中没有你要找的风格),做了的jsfiddle到迎合它:
function getStyleRuleValue(style, selector, sheet) {
var sheets = typeof sheet !== 'undefined' ? [sheet] : document.styleSheets;
for (var i = 0, l = sheets.length; i < l; i++) {
var sheet = sheets[i];
if( !sheet.cssRules ) { continue; }
for (var j = 0, k = sheet.cssRules.length; j < k; j++) {
var rule = sheet.cssRules[j];
if (rule.selectorText && rule.selectorText.indexOf(selector) !== -1 && rule.style[style] !== '') {
return rule.style[style];
}
}
}
return null;
}
Also took out the split in the conditional, not necessary and now it confirms that the style is present in the rule being checked.
还去掉了条件中的拆分,没有必要,现在它确认样式存在于正在检查的规则中。
Just for shigiggles created a jsFiddleto cache the styles by selector:
只是为了 shiggles 创建了一个jsFiddle来通过选择器缓存样式:
var styleCache = {};
function getStyleRuleValue(style, selector, sheet) {
if (typeof styleCache[selector] !== 'undefined') {
if (typeof styleCache[selector][style] !== 'undefined') {
return styleCache[selector][style];
}
}
else {
styleCache[selector] = {};
}
var sheets = typeof sheet !== 'undefined' ? [sheet] : document.styleSheets;
for (var i = 0, l = sheets.length; i < l; i++) {
var sheet = sheets[i];
if( !sheet.cssRules ) { continue; }
for (var j = 0, k = sheet.cssRules.length; j < k; j++) {
var rule = sheet.cssRules[j];
if (rule.selectorText && rule.selectorText.indexOf(selector) !== -1 && rule.style[style] !== '') {
return styleCache[selector][style] = rule.style[style];
}
}
}
return null;
}
Although if you do use that, I would suggest putting it in a closure/class. Thanks again to rlemonfor the awesome original.
虽然如果你使用它,我建议把它放在一个闭包/类中。再次感谢rlemon的精彩原创。
回答by dude
I've just wrote this function get all styles by a selector. Notice: The selector must be the same as in the CSS.
我刚刚编写了这个函数,通过选择器获取所有样式。注意:选择器必须与 CSS 中的选择器相同。
/**
* Gets styles by a classname
*
* @notice The className must be 1:1 the same as in the CSS
* @param string className_
*/
function getStyle(className_) {
var styleSheets = global_.document.styleSheets;
var styleSheetsLength = styleSheets.length;
for(var i = 0; i < styleSheetsLength; i++){
var classes = styleSheets[i].rules || styleSheets[i].cssRules;
var classesLength = classes.length;
for (var x = 0; x < classesLength; x++) {
if (classes[x].selectorText == className_) {
var ret;
if(classes[x].cssText){
ret = classes[x].cssText;
} else {
ret = classes[x].style.cssText;
}
if(ret.indexOf(classes[x].selectorText) == -1){
ret = classes[x].selectorText + "{" + ret + "}";
}
return ret;
}
}
}
}
回答by Tom Dunn
Here's another method: add a hidden div with the class applied. Use jQuery.css to look up the style value. Then remove the element.
这是另一种方法:添加一个应用了类的隐藏 div。使用 jQuery.css 查找样式值。然后移除元素。
http://plnkr.co/edit/Cu4lPbaJWHW42vgsk9ey
http://plnkr.co/edit/Cu4lPbaJWHW42vgsk9ey
function getStyleValue(className, style) {
var elementId = 'test-' + className,
testElement = document.getElementById(elementId),
val;
if (testElement === null) {
testElement = document.createElement('div');
testElement.className = className;
testElement.style.display = 'none';
document.body.appendChild(testElement);
}
val = $(testElement).css(style);
document.body.removeChild(testElement);
return val;
}
console.log( 'The style value is ' + getStyleValue('dark-red', 'color') );
回答by Лёша Ан
Why don't add .highlighted
class, cache the color
style, than remove it and animate to cached color? I.e. don't append elements and don't parse & loop styles.
为什么不添加.highlighted
类,缓存color
样式,而不是删除它并为缓存的颜色设置动画?即不附加元素,也不解析 & 循环样式。
var $element = $('.my-class').addClass('highlighted');
var colorToAnimate = $element.css('color');
$element.removeClass('highlighted');
alert(colorToAnimate);
.my-class {
color: blue;
}
.highlighted {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<span class="my-class">Animated color text</span>