【问题标题】:How to compare colors in JavaScript?如何在 JavaScript 中比较颜色?
【发布时间】:2012-03-14 08:09:29
【问题描述】:

为什么这不起作用?即使颜色 等于 #ECECF4,它仍然会提示“否”。 它正在选择我测试过的正确元素。有没有更好的写法?

<script type="text/javascript">

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

</script>

【问题讨论】:

  • 这个脚本放在哪里/什么时候运行?
  • 放在这里
    1
    并在点击时运行
  • 颜色代码以小写形式存储。所以#ececf4 会起作用。
  • @Teemu #ececf4 仅适用于 IE。

标签: javascript html css


【解决方案1】:

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

相反,将逻辑保存在 JavaScript 中,并根据保存在某处的状态执行操作。然后,如果您想通过改变颜色向用户发送视觉反馈,请为元素添加一个类。这样一来,JavaScript 只知道类名,并且样式总是在 CSS 中按应有的方式隔离。

$(".list").on("click", "li", function(){
    $(this).toggleClass('active');
});
.list {
  width: 100%;
  padding: 0;
}
.list li {
  padding: 5px 10px;
  list-style: none;
  cursor: pointer;
}
.list li:hover {
  background-color: rgba(0, 0, 0, 0.05);
}
.list li.active {
  background-color: #eeeecc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="list">
  <li>test 1</li>
  <li>test 2</li>
  <li>test 3</li>
</ul>

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

请注意,#ECECF4rgb(236, 236, 244) 的颜色相同,但表示形式不同。

IE7和IE8输出HEX值,IE9及以上等浏览器输出RGB格式。因此,将颜色与跨浏览器兼容性进行比较是一项棘手的任务,best way to do it isn't beautiful

我做了一个简单的函数,它适用于大多数浏览器的大多数情况,即使是通过 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>

我使用javascript:weekclick.call(this) 调用weekclick 函数,将元素本身作为回调的上下文传递,从而可以轻松地使用this 访问元素。

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


当我在 2012 年最初写这个答案时,我使用 navigator.appName === "Microsoft Internet Explorer" 来知道它是否是 IE7,并且要比较的颜色已更改为它的 HEX 等效项。不要这样做,因为它今天行不通。

【讨论】:

    【解决方案2】:

    使用canvas 比较颜色。

    • 使用颜色字符串填充一个像素
    • 和另一个像素使用元素getComputedStyle颜色属性
    • 比较两个像素data 使用Array.fromJSON.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 覆盖的值

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

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

    为什么是画布?

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

    有用的链接:

    【讨论】:

      【解决方案3】:

      我实际上只是在学习 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")
      

      【讨论】:

      • 虽然无需过多添加代码就可以很好地工作,但我发现仅出于比较它们的颜色的目的而在页面中抓取另一个元素是低效的。
      【解决方案4】:

      这种方式建议使用 JQuery 的 background-color 标准化对 rgb(r, g, b) 的响应。

      How to get the background color of an element using javascript?

      【讨论】:

        【解决方案5】:

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

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

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

        【讨论】:

          【解决方案6】:

          我建议使用 '===' stric equal(我认为这是名称)。

          喜欢:

          if (document.getElementById('test').style.backgroundColor === "rgb(236, 236, 244)") {
          

          【讨论】:

            猜你喜欢
            • 2016-03-31
            • 1970-01-01
            • 2011-01-23
            • 2013-02-22
            • 2015-11-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多