jQuery-基于复选框标签背景颜色的CSS颜色

时间:2019-05-19 04:50:39

标签: jquery css

对于每个checked复选框,我试图运行以下功能,根据{{1}的暗度将color更改为白色/黑色 }}。但是,第三个复选框应该足够暗,可以将文本颜色更改为白色,但无法执行。

background-color

尝试使用以下电话进行呼叫:

   function isDark(color) {
    var match = /rgb\((\d+).*?(\d+).*?(\d+)\)/.exec(color);
    return (
      (match[1] & 255) + (match[2] & 255) + (match[3] & 255) < 3 * 256 / 2
    );
  }

以下是参考代码笔,该功能可以单独运行:

https://codepen.io/moofawsaw/pen/RmZWaL

label.css(
  "color",
  isDark(label.css("background-color")) ? "white" : "black"
);
$(document).ready(function() {
  function isDark(color) {
    var match = /rgb\((\d+).*?(\d+).*?(\d+)\)/.exec(color);
    return (match[1] & 255) + (match[2] & 255) + (match[3] & 255) < 3 * 256 / 2;
  }
  $(".item").each(function() {
    var item = $(this).find(".input");
    var color = $(this)
      .find("label")
      .attr("data-color");
    item.change(function() {
      var label = $(this).closest(".item");
      var dot = $(this)
        .closest(".item")
        .find(".dot");
      var cancel = $(this)
        .closest(".item")
        .find(".cancel");
      if ($(this).prop("checked")) {
        var val = 0;
        dot.css({
          "-webkit-transform": "scale(" + val + ")",
          "-moz-transform": "scale(" + val + ")",
          "-ms-transform": "scale(" + val + ")",
          "-o-transform": "scale(" + val + ")",
          transform: "scale(" + val + ")",
          width: "0px"
        });
        label.css("background-color", color);
        cancel.css("display", "flex");
        label.css(
          "color",
          isDark(label.css("background-color")) ? "white" : "black"
        );
      } else {
        var val = 1;
        label.css("background-color", "");
        dot.css({
          "-webkit-transform": "scale(" + val + ")",
          "-moz-transform": "scale(" + val + ")",
          "-ms-transform": "scale(" + val + ")",
          "-o-transform": "scale(" + val + ")",
          transform: "scale(" + val + ")",
          width: "12px"
        });
        cancel.css("display", "none");
        label.css("color", "");
      }
    });
  });
});
label {
  display: flex;
  align-items: center;
  margin-left: 6px;
  font-size: 12px;
  line-height: 16px;
  font-weight: 400;
  padding: 4px 0;
  font-family: Roboto Mono, arial, sans-serif;
  letter-spacing: -0.2px;
  user-select: none;
  cursor: pointer;
  transition: all 0.25s ease;
}

input {
  display: none;
  visibility: hidden;
}

.boxes {
  display: flex;
  padding: 3rem
}

.item {
  background-color: white;
  padding-left: 8px !important;
  padding-right: 8px !important;
  border: 1px solid #dadce0;
  border-radius: 6px;
  display: flex;
  align-items: center;
  margin: .3rem;
  transition-property: all;
  transition-duration: 0.1s;
  transition-timing-function: ease-in-out;
}

.cancel {
  padding: 0px 6px;
  display: none;
  transition: all 0.25s ease;
}

.dot {
  border-radius: 50%;
  width: 12px;
  height: 12px;
  transition: all 0.25s ease;
}

.item:nth-child(1) .dot {
  background: rgb(255, 64, 129);
}

.item:nth-child(2) .dot {
  background: rgb(49, 231, 182);
}

.item:nth-child(3) .dot {
  background: blue;
}

1 个答案:

答案 0 :(得分:1)

更新

已添加另一个演示。我编写了一个迷你插件,为.dot.cancel设置了动画。 参见演示2


  

“然而,第三个复选框应该足够暗才能将文本颜色更改为白色,但无法执行。”

如果isDark()确实可以工作(实际上不起作用),则第三个按钮将保持不变。原因是因为它的data-color属性在应为rgb(0,0,255)时具有“ blue”作为值。 isDark()将返回false,因为“ blue”是无效的参数。即使是正确的isDark()也总是会返回false,因为它有很多语法错误:

function isDark(color) {
  var match = /rgb\((\d+).*?(\d+).*?(\d+)\)/.exec(color);
  return (match[1] & 255) + (match[2] & 255) + (match[3] & 255) < 3 * 256 / 2;
}
  1. 使用正则表达式提取数字不是一个好主意。由于数字来自任意来源(示例中的data-color(示例中的data-rgb),因此请像这样保留数字:data-rgb="0,0,255"

  2. .exec()方法将仅返回一个字符串数组,其原因有两个:1.它需要运行while循环才能继续搜索多个匹配项。 2.正则表达式将匹配整个字符串一次,因为它必须匹配3个单独的数字。因此match[1]match[2]match[3]根本就不存在,只有match[0](数组是0索引)。

  3. 您在哪里找到的:... & 255)?根本没有任何意义。另外,3 * 256 / 2就是384(它是rgb(128,128,128)的总和,它是黑白之间的颜色...灰色)。

因此整个OP代码已更改isDark()仅有两行,但差异最大。出于效率方面的考虑,对HTML,CSS和JavaScript的其余部分进行了更多的更改,而不是为了错误。

演示1

$(':checkbox').on('change', function(e) {
  var item = $(this).closest(".item");
  var label = $(this).next("label");
  var dot = label.find(".dot");
  var cancel = label.find(".cancel");
  var color = label.data('rgb');
  var rgb = `rgb(${color})`;
  var contrast = darkness(color) ? "black" : "white";

  if (this.checked) {
    dot.toggleClass('off on');
    item.css({
      "background-color": rgb,
      "color": contrast
    });
    cancel.css('color', contrast);
  } else {
    dot.toggleClass('off on');
    item.css({
      "background-color": "#fff",
      "color": '#000'
    });
    cancel.css('color', 'white');
  }
});

function darkness(color) {
  color.replace(/^\D+|\)/g, '').trim();
  //console.log(color);
  var rgb = color.split(',');
  //console.log(rgb);
  var final = (parseInt(rgb[0], 10) + parseInt(rgb[1], 10) + parseInt(rgb[2], 10));
  //console.log(final);
  if (final < 384) {
    return false;
  }
  return true;
}
label {
  display: flex;
  align-items: center;
  font: 400 12px/16px Roboto Mono, monospace;
  letter-spacing: -0.2px;
  padding: 4px 0;
  margin-left: 6px;
  user-select: none;
  cursor: pointer;
  transition: all 0.25s ease;
}

input {
  display: none;
}

.boxes {
  display: flex;
  padding: 3rem;
  list-style: none;
}

.item {
  display: flex;
  align-items: center;
  background-color: #fff;
  min-width: 100px;
  border: 1px solid #dadce0;
  border-radius: 6px;
  padding-left: 8px;
  padding-right: 8px;
  margin: 0.3rem;
  transition: 0.1s ease-in-out;
}

.text {
  display: inline-block;
  min-width: 50px;
}

.cancel {
  display: inline-block;
  color: #fff;
  padding: 0px 6px;
  transition: all 0.25s ease;
}

.dot {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  margin-right: 20px;
  transition: all 0.25s ease;
}

.dot.off {
  transform: scale(0);
}

.dot.on {
  transform: scale(1);
}

#i0+label .dot {
  background-color: rgb(255, 64, 129);
}

#i1+label .dot {
  background-color: rgb(49, 231, 182);
}

#i2+label .dot {
  background-color: rgb(0, 0, 255);
}
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono&display=swap" rel="stylesheet">
<link href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" rel="stylesheet" crossorigin="anonymous">

<ul class="boxes">

  <li class="item">
    <input id="i0" type="checkbox">
    <label data-rgb="255,64,129" for="i0">
    <mark class="dot on"></mark>
    <b class='text'>Lobster</b>
    <i class="fas fa-times cancel"></i>
  </label>
  </li>

  <li class="item">
    <input id="i1" type="checkbox">
    <label data-rgb="49,231,182" for="i1">
    <mark class="dot on"></mark>
    <b class='text'>Tuna</b>
    <i class="fas fa-times cancel"></i>
  </label>
  </li>

  <li class="item">
    <input id="i2" type="checkbox">
    <label data-rgb="0,0,255" for="i2">
    <mark class="dot on"></mark>
    <b class='text'>Pine</b>
    <i class="fas fa-times cancel"></i>
  </label>
  </li>

</ul>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


演示2

$(function() {

  $(':checkbox').on('change', function(e) {
    var item = $(this).parent();
    var dot = $(this).next();
    var text = dot.next();
    var cancel = text.next();
    var color = $(this).val();
    var rgb = `rgb(${color})`;
    var contrast = darkness(color) ? "black" : "white";

    if (this.checked) {
      item.css({
        "background-color": rgb,
        "color": contrast
      });

      dot.toggleClass('on off');
      cancel.css('color', contrast).toggleClass('on off');
    } else {
      item.css({
        "background-color": "#fff",
        "color": '#000'
      });

      dot.toggleClass('on off');
      cancel.toggleClass('on off');
    }
    dot.icons();
    cancel.icons();
  });

  function darkness(color) {
    color.replace(/^\D+|\)/g, '').trim();
    //console.log(color);
    var rgb = color.split(',');
    //console.log(rgb);
    var final = (parseInt(rgb[0], 10) + parseInt(rgb[1], 10) + parseInt(rgb[2], 10));
    //console.log(final);
    if (final < 384) {
      return false;
    }
    return true;
  }

  (function($) {
    $.fn.icons = function() {
      return this.each(function() {
        if ($(this).hasClass('off')) {
          $(this).animate({
            'transform': 'scale(0)',
            'width': '0',
          }, 250);
          $(this).hide();
        } else if ($(this).hasClass('on')) {
          $(this).animate({
            'transform': 'scale(1)',
            'width': '12px'
          }, 250);
          $(this).show();
        } else {
          return false;
        }
      });
    }
  })(jQuery);
  $('.dot, .cancel').icons();
});
.boxes {
  display: flex;
  justify-content: space-around;
  width: max-content;
  padding: 3rem;
}

.item {
  display: flex;
  align-items: center;
  width: fit-content;
  background-color: #fff;
  border: 1px solid #dadce0;
  border-radius: 6px;
  padding: 0 8px;
  margin: 0 4px;
  cursor: pointer;
  transition: 0.15s ease;
}

input {
  display: none;
}

.dot {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  transition: all 0.25s ease-out;
}

.text {
  font: 700 12px/16px Roboto Mono, monospace;
  letter-spacing: -0.2px;
  padding: 4px 0;
  margin: 0 6px;
  user-select: none;
  transition: all 0.25s ease;
}

.text::before {
  content: attr(value);
}

.cancel {
  display: none;
  color: #000;
  font-size: 12px;
  width: 12px;
  transition: all 0.35s ease;
}

#i0+.dot {
  background-color: rgb(255, 64, 129);
}

#i1+.dot {
  background-color: rgb(49, 231, 182);
}

#i2+.dot {
  background-color: rgb(0, 0, 255);
}
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono&display=swap" rel="stylesheet">
<link href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" rel="stylesheet" crossorigin="anonymous">

<form class="boxes">

  <label class="item" for='i0'>
    <input id="i0" type="checkbox" value="255,64,129">
    <mark class="dot on"></mark>
    <output class='text' for='i0' value='Lobster'>
    </output>
    <i class="fas fa-times cancel off"></i>
  </label>

  <label class="item" for='i1'>
    <input id="i1" type="checkbox" value="49,231,182">
    <mark class="dot on"></mark>
    <output class='text' for='i1' value='Tuna'></output>
    <i class="fas fa-times cancel off"></i>
  </label>

  <label class="item" for='i2'>
    <input id="i2" type="checkbox" value="0,0,255">
    <mark class="dot on"></mark>
    <output class='text' for='i2' value='Clam'></output>
    <i class="fas fa-times cancel off"></i>
  </label>

</form>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>