根据背景颜色改变颜色

3

我正在尝试根据背景颜色更改颜色,使文本更易读。

在搜索过程中,我找到了这个:

var rgb = $('.external-event').css('background-color');
var c = 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')';
var o = Math.round(((parseInt(rgb[0]) * 299) + (parseInt(rgb[1]) * 587) + (parseInt(rgb[2]) * 114)) / 1000);

//console.log(o);
if (o > 125) {
  $('.external-event').css('color', 'black');
} else {
  $('.external-event').css('color', 'white');
}

$('.external-event').css('background-color', c);

var r = Math.round(Math.random() * 255);
var g = Math.round(Math.random() * 255);
var b = Math.round(Math.random() * 255);

rgb[0] = r;
rgb[1] = g;
rgb[2] = b;

问题在于它只显示白色,而不是变成黑色。

我做错了什么?

这里有一个JSFiddle

由于某种原因,此示例与我的实际开发环境相反,并保持文本为黑色,即使有黑色背景。

编辑:我忘记添加了我动态显示多个背景颜色的同一类.external-event,并且似乎只获取第一个元素的RGB值。


1
你已经将rgb声明为JQuery包装集中第一个元素的背景颜色,该集合包含所有与.external-event选择器匹配的元素。然后,您将rgb视为数组,并使用rgb [0]rgb [1]rgb [2]将生成的颜色值分配给它。 - Scott Marcus
@ScottMarcus 实际上,使用单个参数的 css 返回表示元素的该样式属性值的字符串。不过他仍在错误地使用它... - Will P.
@WillP。这正是我的评论所说的。 - Scott Marcus
使用jQuery,您将从rgb [0]获取“r”,因为它将返回一个字符串。我认为您正在寻找其他东西。https://jsfiddle.net/txnr70jL/1/ - oqx
2个回答

2
问题:

.css('background-color') 返回一个表示背景颜色的字符串字面量,格式为函数格式 - 即rgb(R,G,B),其中R是红色值,G是绿色值,B是蓝色值。

第一个字符(即rgb[0])将是r,第二个字符将是g,以此类推... 此外,将字符传递给 parseInt() (即 parseInt(rgb[0]))会产生NaN。因此,NaN > 0 将始终评估为false。这就是为什么您的代码示例始终将(文本前景)颜色设置为白色的原因。

解决方案:

为了获取红、绿和蓝色数字的各个值,一种选择是使用 String.replace() 去掉 rgb(),然后使用 String.split() 将这些值分割成一个数组,就像这样:
var rgbValues = rgb.replace('rgb(','').replace(')','').split(', ');
//rgbValues:  ["0", "0", "0"]

另一种选择是使用正则表达式进行匹配,就像下面的示例中使用 .match() 一样。
var rgb = $('.external-event').css('background-color');
var pattern = /rgb\((\d+),\s?(\d+),\s?(\d+)\)/;
//matches will be an array containing the elements:
//0- the group matched i.e. rgb(0, 0, 0)
//1- the r value
//2- the g value
//3- the b value
var matches = rgb.match(pattern);

注意:还请参阅下面有关 parseInt() 的部分。
通过展开下面的片段查看演示。

var rgb = $('.external-event').css('background-color');
//remove the rgb() characters and split into an array
var rgbValues = rgb.replace('rgb(','').replace(')','').split(', ');
//or use a regular expression
var pattern = /rgb\((\d+),\s?(\d+),\s?(\d+)\)/;
var matches = rgb.match(pattern);
if (matches.length && matches.length > 3) {
  var c = 'rgb(' + matches[1] + ',' + matches[2] + ',' + matches[3] + ')';
  var o = Math.round(((parseInt(matches[1], 10) * 299) + (parseInt(matches[2], 10) * 587) + (parseInt(matches[3], 10) * 114)) / 1000);

  console.log('rgb: ', rgb, ' c: ', c, ' o : ', o, ' matches: [' + matches.join(", ")+']', ' rgbValues: [' + rgbValues.join(", ")+']');
  if (o > 125) {
    $('.external-event').css('color', 'black');
  } else {
    $('.external-event').css('color', 'white');
  }

  $('.external-event').css('background-color', c);
}
.external-event {
  background-color: #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="external-event">
  <br />external event
  <br />
</div>

编辑

问题 已经编辑,声明为“我忘记添加了,我正在动态显示多个具有相同类*.external-event* 的背景颜色,但似乎只获取第一个元素的 RGB 值。

使用 jQuery 方法 .each() 迭代包含类 .external-event 的元素。回调可以接受两个 参数:索引以及元素(在回调上下文中与this相同)。

var externalEvents = $('.external-event');
    externalEvents.each(function(index, externalEvent) {
        //check background color of externalEvent - 
        //$(this) == $(externalEvent)

请看下面代码片段的扩展演示。

$(function() { //jQuery DOM-loaded callback
  var externalEvents = $('.external-event');
  externalEvents.each(function(index, externalEvent) {
    var rgb = $(externalEvent).css('background-color');
    //remove the rgb() characters and split into an array
    var rgbValues = rgb.replace('rgb(', '').replace(')', '').split(', ');
    //or use a regular expression
    var pattern = /rgb\((\d+),\s?(\d+),\s?(\d+)\)/;
    var matches = rgb.match(pattern);
    if (matches.length && matches.length > 3) {
      var c = 'rgb(' + matches[1] + ',' + matches[2] + ',' + matches[3] + ')';
      var o = Math.round(((parseInt(matches[1], 10) * 299) + (parseInt(matches[2], 10) * 587) + (parseInt(matches[3], 10) * 114)) / 1000);

      console.log('rgb: ', rgb, ' c: ', c, ' o : ', o, ' matches: [' + matches.join(", ")+']', ' rgbValues: [' + rgbValues.join(", ")+']');
      if (o > 125) {
        $(externalEvent).css('color', 'black');
      } else {
        $(externalEvent).css('color', 'white');
      }
      //This isn't needed
     // $(externalEvent).css('background-color', c);
    }
  });
});
.external-event {
  background-color: #000;
}

.external-event.orange {
  background-color: #fa0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="external-event">
  <br />external event
  <br />
</div>
<div class="external-event orange">
  <br />external event orange
  <br />
</div>

关于使用parseInt()的注意事项:

通常在使用parseInt()时,将基数(通常为10)作为参数传递是一个好习惯,原因如下:

如果未定义或为0(或不存在)基数,则JavaScript会假定以下内容:

  • 如果输入字符串以“0x”或“0X”开头,则基数为16(十六进制),并解析字符串的其余部分。
  • 如果输入字符串以“0”开头,则基数为8(八进制)或10(十进制)。具体选择哪个基数取决于实现。ECMAScript 5指定使用10(十进制),但不是所有浏览器都支持这一点。因此,在使用parseInt时始终要指定基数。
  • 如果输入字符串以其他任何值开头,则基数为10(十进制)。1
所以将基数设为10,像下面这样:
parseInt(matches[1], 10)

0

Sam Onela的回答的帮助下,我终于搞明白了。

这是我所做的:

$('.external-event').each(function() {

    var rgb = $(this).css('background-color');
    var pattern = /rgb\((\d+),\s?(\d+),\s?(\d+)\)/;
    var matches = rgb.match(pattern);

    var o = Math.round(((parseInt(matches[1]) * 299) + (parseInt(matches[2]) * 587) + (parseInt(matches[3]) * 114)) /1000);

    //console.log(o);
    if(o > 125) {
        $(this).css('color', '#444444');
    }else{
        $(this).css('color', 'white');
    }

});

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