获取元素的真实背景颜色?

18

目前我想获取指定对象的真实背景颜色,这里的真实是指人们看到的,例如,给定以下代码:

<div id="foo" style="background-color: red">
    I am red
    <span id="bar">
         I have no background, but I am red
    </span>
</div>
< p > #bar元素的实际背景颜色应为rbg(255,0,0)。

< p >以下是目前为止的内容:

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)";
}

但是有更好的方法吗?

在Stack Snippet和jsFiddle中演示

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>


认为你的例子非常接近,可以遍历父级元素直到找到颜色。 - Tim M.
3
@TimMedora,但是如果#bar的位置不在#foo的上方呢?我的意思是#bar{ position: ...; left: ..., top: ...} - Marcus
那是个好问题。您可以检查页面上元素的尺寸/位置以确定交集,但我想除非页面上只有几十个元素或者您能找到一种将其限制在小区域内的方法,否则速度会变慢。 - Tim M.
@TimMedora,是的,这实际上是浏览器所做的... - Marcus
我认为这个问题可以帮助你:https://dev59.com/nHI-5IYBdhLWcg3wR2Jr - Charles Jourdan
请注意,这个问题并不是完全可以回答的,因为对于任何元素矩形,其他元素都可能部分重叠它。因此,对于任何元素矩形,您可以在同一个矩形内拥有许多可见的背景颜色。而且还要忽略图案和图像的复杂性。我希望你能做到的最好的事情就是获取特定x-y点的颜色和不透明度。 - Memetican
5个回答

18

仅使用Javascript的版本:

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)

http://jsfiddle.net/qnLwsr7y/

请注意,它不考虑透明度或背景图片。


如果父元素设置了 background-image,此方法将失败,请参考:https://jsfiddle.net/38ve0gdv/1/。 - cronfy
1
考虑添加此检查:https://jsfiddle.net/38ve0gdv/2/,如果找到父元素的“background-image”,则返回`undefined`作为背景。 - cronfy

7

试试这个:

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
    }
}

http://jsfiddle.net/bqkwN/


你不会从 $(“#bar”)中删除 red - Marcus
@Marcus #bar没有background-color属性。所以你想获取#bar的父元素的背景颜色? - Ram
是的,就像我在问题中提到的那样,人们看到的背景颜色是指“background-color”。 - Marcus
但如果没有背景,则返回“undefined”。 - Toolkit

7

不总是正常工作 https://dev59.com/Bn7aa4cB1Zd3GeqPpmad - Sanghyun Lee
2
在我的最简单的情况下,这总是在Chrome中返回rgba(0,0,0,0)。而遍历元素树则运行良好(见下文)。 - Pavel Vlasov

4
这是一件难以做到完美的事情 :( 我认为在所有情况下都能得到100%正确的结果是不可能的。
background-color不会被继承。getComputedStyle只返回elem.style.backgroundColor中有的内容,或者从已加载的CSS样式表中派生出来的内容。如果这两个都没有返回值,则返回rgba(0, 0, 0, 0),此时您需要向上爬DOM以查看哪些父元素具有背景颜色。在框架的情况下,这更加复杂,因为它们可能从它们后面的(即顶部)框架中派生其背景。
以下是一个尝试:
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 '';
  }
}

这种方法存在一个问题,如果有人在元素的样式或CSS样式表中明确设置了元素的背景为rgba(0, 0, 0, 0),则您可能需要使用该值而不是计算出的值,这种情况下该代码将无法正常工作。


-2

试试这个:

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);
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接