问题很简单;使用jQuery的css
函数,可以返回CSS属性的计算样式,但如果要呈现的属性有多个样式,该怎么办?例如:
<div id="foo" style="text-decoration:underline;">Some underline text</div>
指令$('#foo').css('text-decoration');
将返回underline
。现在,如果我将其更改为
<div id="foo" style="text-decoration:underline;">Some underline <span id="bar" style="text-decoration:line-through;">text</span></div>
指令$('#bar').css('text-decoration');
将返回line-through
,好吧。
但实际文字也是 underline
!我怎么能两个都回来?如果我想知道某些文字是underline
还是line-through
,我是否需要搜索所有祖先?听起来有点痛苦,不是吗?
** 修改 **
这个HTML出现了另一个问题
<span style="text-decoration:underline;">some <span id="e1" style="font-weight:bold;">text</span></span>
其中$('#e1').css('text-decoration');
由于某种原因返回none
,而文字则使用下划线清晰呈现。
** 免责声明 **
这个问题不是要讨论UA如何呈现元素,而是元素层次结构是否应用了CSS。如果想要更好地理解text-decoration
,我建议人们read about it。这个问题试图关注更广泛的问题。例如,它也可以应用于此HTML
<div style="display:none;">Some <span id="keyword" style="text-decoration:underline;">hidden</span> text</div>
在哪里可以想知道元素keyword
是否可见。使用下面的代码,只需使用
cssLookup($('#keyword'), 'display', 'none'); // -> true
** 更新 **
在完成所有答案和评论之后,基于Brock Adams解决方案:
/**
* Lookup the given node and node's parents for the given style value. Returns boolean
*
* @param e element (jQuery object)
* @param style the style name
* @param value the value to look for
* @return boolean
*/
function cssLookup(e, style, value) {
var result = (e.css(style) == value);
if (!result) {
e.parents().each(function() {
if ($(this).css(style) == value) {
result = true;
return false;
}
});
}
return result;
}
谢谢大家的意见。
答案 0 :(得分:2)
我认为任何浏览器或W3C都不提供这样做的好方法。
一个复杂的因素是知道哪些样式取消了前面的样式(例如,下划线与非下划线)。
因此,我们需要多个查找表或人工判断来了解实际应用的样式。
最后,所有这些方法(目前为止的3个答案)都无法区分空白或缺失的样式设置和明确设置的none
。显然,浏览器可以呈现明确设置的none
,而不是空白或缺少设置。
对于人类使用,此代码应该可以解决问题:
function cssTree (jNode, styleName, bShowBlanks) {
var styleArray = [jNode.css (styleName)];
jNode.parents ().map ( function () {
var style = $(this).css (styleName);
if (bShowBlanks || ! /^(none|\s*)$/i.test (style) )
styleArray.push (style);
} );
return styleArray;
}
alert ( cssTree ( $("#bar"), 'text-decoration') );
<强>结果:强>
bar: line-through,underline
el: none,underline
//-- With bShowBlanks = true.
bar: line-through,underline,none,none
el: none,underline,none,none
答案 1 :(得分:1)
这是一个可能的解决方案:
function getVisualCSS(tag, elem){
var styles = [];
var thisStyle = $(elem).css(tag);
if(thisStyle != 'none') styles.push(thisStyle);
while($(elem).parent()[0].tagName != 'BODY'){
styles.push($(elem).parent().css(tag));
elem = $(elem).parent();
}
styles.push($(elem).parent().css(tag));
return $.unique($.grep(styles, function(n){
return n != 'none';
}));
}
它的作用是,它检查给定CSS标记的所有元素祖先。
为了“清理”数组,将删除所有none
值,并仅返回唯一值。
答案 2 :(得分:1)
好的,这不是您正在寻找的简单,优雅的答案,但我在这里有一个工作选项:http://jsfiddle.net/nrabinowitz/Uu6p3/1/
它与概念中的@Tir相似,但使用内置的jQuery函数来查找所有祖先,将其text-decoration
样式映射到数组中,过滤不等于"none"
的唯一值,并返回样式数组:
/**
* Generic function to find all values for
* CSS settings that allow multiple values.
*
* @param {String} selector JQuery selector
* @param {String} attr CSS attribute to look for
* @param {String[]} ignore Values to ignore
*/
function findAllCssValues(selector, attr, ignore) {
var temp = {};
ignore = ignore || ['none'];
return $.grep(
// create the array of all values
$(selector)
// select element and all ancestors
.parents().andSelf()
// put all css attribute results into an array
.map(function() {
return $(this).css(attr)
})
// make it a regular Javascript array
.toArray(),
// now filter for unique values that aren't "none"
function(val) {
if (val in temp || $.inArray(val, ignore) >= 0) {
return false;
}
temp[val] = true;
return true;
}
);
}
findAllCssValues('#bar', 'text-decoration');
它适用于所有示例代码段,如小提琴中所示。我使它适用于任何CSS属性,但我不确定此问题是否适用于text-decoration
以外的任何内容。
答案 3 :(得分:-1)
如果您尝试将内部范围设置为text-decoration:none
,您会注意到仍然会从父div渲染下划线。问题是文本修饰不会继承,但它会像它一样呈现。
因此,任何文本元素都将呈现其父项的文本装饰的所有的组合,即使它或其任何父项的文本修饰设置为无。
如果您想知道已应用于文本的所有文本装饰,您需要将链条直接走到顶部并记录您遇到的所有装饰的组合,不包括“无”。这是一个例子:
function findDecoration( elem ) {
var $elem = $(elem);
var found = new Array();
var dec = "";
var current = $elem.css('text-decoration');
if ( current != 'none' ) {
found[ current ] = 1;
dec = current;
}
var p = $elem.parent();
while ( p != null && p.get(0).nodeName.toLowerCase() != 'body' ) {
current = p.css('text-decoration');
if ( current != 'none' && found[ current ] == null ) {
found[ current ] = 1;
dec = current + " " + dec;
}
p = p.parent();
}
return dec;
}