如何比较 JavaScript 中的颜色?

IT技术 javascript html css
2021-01-28 03:31:14

为什么这不起作用?即使颜色等于#ECECF4它仍然提醒“否”。它正在选择正确的元素,因为我已经对其进行了测试。有没有更好的方法来写这个?

<script type="text/javascript">

function weekclick() {
    if (document.getElementById('w1').style.backgroundColor == "#ECECF4") {
        alert("Yes");
    } else {
        alert("No");
    }
}

</script>
6个回答

应不惜一切代价避免将颜色作为业务逻辑的一部分进行比较。

相反,将逻辑保留在 JavaScript 中并根据保存在某处的状态进行操作。然后,如果您想通过颜色变化向用户发送视觉反馈,请向元素添加一个类。这样,JavaScript 只知道类名,并且样式在 CSS 中始终是孤立的。


话虽如此,OP 的代码适用于 Chrome 17.0.963.56 和 Firefox 8.0。当您不知道要比较什么时,只需使用console.log()它来查看它的外观。

请注意,#ECECF4它与颜色相同,rgb(236, 236, 244)但表示方式不同。

IE7和IE8输出HEX值,IE9及以上等浏览器输出RGB格式。因此,将颜色与跨浏览器兼容性进行比较是一项棘手的任务,而最好的方法并不美观

我做了一个简单的函数,它适用于大多数浏览器的大多数情况,甚至通过 CSS 设置颜色。

function weekclick() {
    var elemColor = getStyle(this, "backgroundColor"),
        color = "rgb(238, 238, 204)";

    console.log("Broswer returned elem color: ", elemColor);

    // IE7 and IE8 output the hex value
    if (elemColor.slice(0, 1) === '#') elemColor = hexToRgb(elemColor);

    console.log(elemColor, " === ", color, "?", elemColor === color);
}

// Source: https://stackoverflow.com/a/41354868/1218980
// Inspired by: https://stackoverflow.com/a/22744598/1218980
function getStyle(el, prop) {
    return (typeof getComputedStyle !== 'undefined' ?
        getComputedStyle(el, null) :
        el.currentStyle
    )[prop];
}


// Slightly modified version to quickly return a string
// https://stackoverflow.com/a/5624139/1218980
function hexToRgb(hex) {
    // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
    var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
    hex = hex.replace(shorthandRegex, function(m, r, g, b) {
        return r + r + g + g + b + b;
    });

    var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
    return result ? "rgb(" + [
        parseInt(result[1], 16),
        parseInt(result[2], 16),
        parseInt(result[3], 16)
    ].join(', ') + ")" : null;
}
#css-div {
  background-color: #eeeecc;
}
<div style="Background-color:#eeeecc" onclick="javascript:weekclick.call(this);">#eeeecc</div>
<div style="Background-color:#EEC" onclick="javascript:weekclick.call(this);">#EEC</div>
<div style="background-color:hsla(60, 50%, 86.7%, 1)" onclick="javascript:weekclick.call(this);">hsla(60, 50%, 86.7%, 1)</div>
<div style="background-color:rgb(238, 238, 204)" onclick="javascript:weekclick.call(this);">rgb(238, 238, 204)</div>
<div id="css-div" onclick="javascript:weekclick.call(this);">css</div>

通过将元素本身作为回调的上下文来调用该weekclick函数javascript:weekclick.call(this),从而可以轻松地使用this.

在使用 HSLA 或 RGBA 时,可以扩展它以将 alpha 考虑在内。


当我最初在 2012 年写下这个答案时,我曾经navigator.appName === "Microsoft Internet Explorer"知道它是否是 IE7 并且要比较的颜色已更改为其等效的十六进制颜色。不要这样做,因为它今天不起作用。

使用 acanvas来比较颜色。

  • 使用颜色字符串填充一个像素
  • 另一个像素使用元素getComputedStyle颜色属性
  • data使用Array.from比较两个像素JSON.stingify

/**
 * Test if Element color property holds a specific color.
 * https://stackoverflow.com/a/60689673/383904
 * 
 * @param {Object} el The DOM Node Element
 * @param {String} prop A CSS property color property
 * @param {String} color A valid CSS color value
 * @return {Boolean} True if element color matches
 */
function isElPropColor(el, prop, color) {
  const ctx = document.createElement('canvas').getContext('2d');
  ctx.fillStyle = color;
  ctx.fillRect( 0, 0, 1, 1 );
  ctx.fillStyle = getComputedStyle(el, null).getPropertyValue(prop);
  ctx.fillRect( 1, 0, 1, 1 );
  const a = JSON.stringify(Array.from(ctx.getImageData(0, 0, 1, 1).data));
  const b = JSON.stringify(Array.from(ctx.getImageData(1, 0, 1, 1).data));
  ctx.canvas = null;
  return a === b;
}


// TEST (PS: see CSS!):

const el   = document.body;
const prop = 'background-color';

console.log(isElPropColor(el, prop, 'red'));      // obviously true :)
console.log(isElPropColor(el, prop, '#f00'));                  // true
console.log(isElPropColor(el, prop, 'rgb(255, 0, 0)'));        // true
console.log(isElPropColor(el, prop, 'hsl(0, 100%, 50%)'));     // true
console.log(isElPropColor(el, prop, 'hsla(0, 100%, 50%, 1)')); // true
body {background: red; }

但是和为什么

大多数现代浏览器都会计算颜色值并将其转换为RGB/A
但是我们不应该依赖于进行严格的相等比较,例如:

 // (Say the element is really red)
 const isRed = myElement.style.backgroundColor === "rgb(255,0,0)"; // false
  • 错误,因为它实际上是“rgb(255, 0, 0)”,带有空格。
  • 不能保证某些浏览器明天不会转换为“rgba(255, 0, 0, 1)”,或者 HSLA?
  • Edge 和 IE 将返回 CSS 中使用的值或被我们的 JS 覆盖的值

我们无法可靠地比较两种 DIV 样式 getComputedStyle

我们甚至不能创建一个“内存中”的 DIV 元素,因为我们需要 - 将它附加到 DOM,而不是使用getComputedStyle(tempDIVElement, null).getPropertyValue('background-color')它,然后从 DOM 中删除它。这是对 DOM 重新计算、绘制的浪费,并且不能保证某些奇怪的样式表!important不会弄乱我们的临时 DIV 样式,div {background: fuchsia !important; }从而给出误报“是红色?真的!蓝色是蓝色,因为 !important”

为什么是canvas?

  • 画布可以留在内存中。无需附加到 DOM、设置颜色、删除元素。
  • 返回的像素数据始终保证为[R, G, B, A](RGBA 为 0-255 值)
  • 一个奇怪的 CSS 规则不会弄乱指定的颜色

有用的链接:

我实际上只是在学习 javascript,但不是创建一个将 rgb() 转换为十六进制的函数,您可以创建一个与您正在寻找的背景颜色相同的 div,并将其与该 div 的背景颜色进行比较。如果您碰巧已经有该十六进制值的 div,您可以这样做:

//javascript
if (document.getElementId('desiredElementToCompare').style.backgroundColor === document.getElementId('elementWithTheDesiredHexString').style.backgroundColor)

//jQuery
if ($('#desiredElementToCompare').css('background-color') === $('#elementWithTheDesiredHexString').css('background-color')

您可以使用函数创建一个 div,然后像这样进行比较:

var compareHex = (hex) => {
    var hexString = document.createElement('div')
    hexString.style.backgroundColor = `${hex}`
    return hexString.style.backgroundColor
}
//then compare
//javascript
if (document.getElementId('desiredElementToCompare').style.backgroundColor === compareHex("#ECECF4"))

//jQuery
if($('#desiredElementToCompare').css('background-color') === compareHex("#ECECF4")
虽然这在不添加太多代码的情况下效果很好,但我发现为了比较它们的颜色而在页面中抓取另一个元素是低效的。
2021-04-12 03:31:14

这种方式建议使用 JQuerybackground-color来标准化对rgb(r, g, b).

如何使用javascript获取元素的背景颜色?

也许这个答案会有所帮助。将颜色代码转换为十六进制,然后比较每个 RGB 颜色/通道(我不知道这个词)

https://stackoverflow.com/a/25666938/1757214

我认为比较两个数字比比较两个字符串更好更容易