Reputation: 6839
Currently I want to get the real background-color of a specified object, here, the real means what the people see, for instance, given the following code:
<div id="foo" style="background-color: red">
I am red
<span id="bar">
I have no background, but I am red
</span>
</div>
The real background-color of #bar
should be rbg(255,0,0)
.
Here's what I have so far:
function color_visible(color_str) {
return color_str && !(color_str.substr(0, 4) == "rgba" && color_str.substr(-2, 2) == "0)");
}
function get_bgcolor (obj) {
var ret = $(obj).css("background-color");
if (!color_visible(ret)) ret = $(obj).css("bgcolor");
if (color_visible(ret)) return ret;
if (!$(obj).is("body")) return get_bgcolor($(obj).parent());
return "rgb(255, 255, 255)";
}
But is there a better way to do it?
function color_visible(color_str) {
return color_str && !(color_str.substr(0, 4) == "rgba" && color_str.substr(-2, 2) == "0)");
}
function get_bgcolor (obj) {
var ret = $(obj).css("background-color");
if (!color_visible(ret)) ret = $(obj).css("bgcolor");
if (color_visible(ret)) return ret;
if (!$(obj).is("body")) return get_bgcolor($(obj).parent());
return "rgb(255, 255, 255)";
}
console.log(get_bgcolor($("#bar")));
console.log(get_bgcolor($("#baz")));
console.log(get_bgcolor($("#foo")));
console.log(get_bgcolor($("body")));
body {
background-color: yellow;
}
.bg_white {
background-color: #FFF;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<div id="foo" style="background-color: red">
I am red
<span id="bar">
I have no background
</span>
<span id="baz" class="bg_white">
I am white
</span>
</div>
I am yellow
</div>
Upvotes: 18
Views: 11714
Reputation: 8151
Javascript only version:
function realBackgroundColor(elem) {
var transparent = 'rgba(0, 0, 0, 0)';
var transparentIE11 = 'transparent';
if (!elem) return transparent;
var bg = getComputedStyle(elem).backgroundColor;
if (bg === transparent || bg === transparentIE11) {
return realBackgroundColor(elem.parentElement);
} else {
return bg;
}
}
realBackgroundColor(document.querySelector('#element')); // rgb(255, 255, 255)
Note that it does not take opacity or background images into account.
Upvotes: 18
Reputation: 118
window.getComputedStyle(element, null).getPropertyValue("background-color")
This approach is simple and native, but doesn't support IE8
Upvotes: 7
Reputation: 19285
This is a difficult thing to get right :( and I believe a 100% correct result in all cases is impossible.
background-color is not inherited. getComputedStyle only returns what is in elem.style.backgroundColor if there, or otherwise what is derived from the css stylesheets loaded. If these two still don't return a value, it returns rgba(0, 0, 0, 0)
in which case you need to climb up the DOM to see what parents elements have. And this is further complicated in the case of frames which may derive their background from the (ie top) frame behind them.
Here is an attempt:
const getCbgcolor = (elem) => {
if (!getCbgcolor.top) getCbgcolor.top= (() => {
try { return window.top.document.documentElement; } catch(e) { return null; /* CORS */}})()
});
while (true) {
let cbg=window.getComputedStyle(elem).getPropertyValue('background-color');
if (cbg && cbg!='rgba(0, 0, 0, 0)' && cbg!='transparent') return cbg;
if (elem===getCbgcolor.top) return 'initial';
elem = elem.parentElement;
if (!elem) return '';
}
}
(An issues with this is that if someone explicitly set an element's background to rgba(0, 0, 0, 0)
in the element's style or a css stylesheet you may want that value instead of the calculated value which will not work with this code.)
Upvotes: 4
Reputation: 144689
Try this:
var get_bgcolor = function(obj) {
var real = obj.css('background-color');
var none = 'rgba(0, 0, 0, 0)';
if (real === none) {
return obj.parents().filter(function() {
return $(this).css('background-color') != none
}).first().css('background-color');
} else {
return real
}
}
Upvotes: 7
Reputation: 14827
Try this:
function hexc(colorval) {
var parts = colorval.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
delete(parts[0]);
for (var i = 1; i <= 3; ++i) {
parts[i] = parseInt(parts[i]).toString(16);
if (parts[i].length == 1) parts[i] = '0' + parts[i];
}
color = '#' + parts.join('');
}
var color = '';
$('div#foo').click(function() {
var x = $(this).css('backgroundColor');
hexc(x);
alert(color);
})
Upvotes: -2