首页 > 解决方案 > jQuery - 带收音机的切换类

问题描述

我试图只toggleClass使用.on/.offif:checked radio以便 CSS 动画只发生在选定的收音机上。问题是如果不是选定else的,我的代码部分就不会执行。input

$(function() {
  $("#m_clear").on("click", function() {
    $("input:checked").each(function() {
      $(this).prop("checked", false);
      $(this).trigger("change");
    });
  });
  $('input[type=radio]').on("change", function() {
    var label = $(this).next("label");
    var dot = label.find(".dot");
    var tagbox = $(this).closest(".tagbox");
    var cancel = label.find(".cancel--tagbox");
    var color = label.data("rgb");
    var rgb = `rgb(${color})`;
    var contrast = darkness(color) ? "#202124" : "#fdfdfd";

    if ($('input[type=radio]').is(':checked')) {
      cancel.css("color", contrast);
      cancel.toggleClass("on off");
      dot.toggleClass("off on");
      tagbox.css({
        "background-color": rgb,
        color: contrast,
        "border-color": rgb,
        color: contrast
      });
    } else {
      dot.toggleClass("off on");
      cancel.toggleClass("on off");
      tagbox.css({
        "background-color": "#fff",
        color: "",
        "border-color": ""
      });
    }
  });

  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;
  }
});
/*input {
  display: none;
}*/

label {
  display: flex;
  align-items: center;
  font: 400 12px/16px Roboto Mono, monospace;
  letter-spacing: -0.2px;
  padding: 4px 0;
  user-select: none;
  cursor: pointer;
}

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

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

.text--tagbox {
  margin-right: 3px;
}

.cancel--tagbox {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 12px;
  height: 12px;
  margin-top: 3px;
  color: purple;
  transition: all 0.25s ease;
}

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

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

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

.dot.off,
.cancel--tagbox.off {
  width: 0px;
  height: 0px;
  opacity: 0;
}

.dot.on,
.cancel--tagbox.on {
  width: 12px;
  height: 12px;
  opacity: 1;
}

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

#i2+label .dot {
  background-color: rgb(0, 0, 255);
}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<button id="m_clear">Clear All</button>
<div class="tagboxes">
  <div class="tagbox">
    <input id="i0" type="radio" name="radio">
    <label data-rgb="255,64,129" for="i0">
    <mark style="background-color: rgb(255, 64, 129);" class="dot on"></mark>
    <b class='text--tagbox'>Lobster</b>
      <div class="cancel--tagbox off"><i class="fa fa-times"></i></div>
  </label>
  </div>
  <div class="tagbox">
    <input id="i1" type="radio" name="radio">
    <label data-rgb="49,231,182" for="i1">
    <mark class="dot on"></mark>
    <b class='text--tagbox'>Tuna</b>
    <div class="cancel--tagbox off"><i class="fa fa-times"></i></div>
  </label>
  </div>
  <div class="tagbox">
    <input id="i2" type="radio" name="radio">
    <label data-rgb="0,0,255" for="i2">
    <mark class="dot on"></mark>
    <b class='text--tagbox'>Pine</b>
    <div class="cancel--tagbox off"><i class="fa fa-times"></i></div>
  </label>
  </div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

标签: jquery

解决方案


所以做了一些改动。

  • 首先,我将它们存储$('input[type=radio]')在一个变量$radio中,以便以后访问它们
  • 接下来,不是检查是否有任何单选按钮被更改,if 检查是否this.checked会告诉我们是否检查了已更改的单选按钮
  • 如果它被选中,我们需要查看另一个无线电是否被选中并需要恢复。未经检查的收音机不会触发更改事件。所以我们可以找到所有其他带有 的单选按钮$radios.not(this),并在它们上手动触发更改事件
  • 之后,if 和 else 都显式使用addClassremoveClass确保类状态是我们期望它们在元素被选中或未选中时的状态

$(function() {
  $("#m_clear").on("click", function() {
    $("input:checked").each(function() {
      $(this).prop("checked", false);
      $(this).trigger("change");
    });
  });
  var $radios = $('input[type=radio]').on("change", function() {
    var label = $(this).next("label");
    var dot = label.find(".dot");
    var tagbox = $(this).closest(".tagbox");
    var cancel = label.find(".cancel--tagbox");
    var color = label.data("rgb");
    var rgb = `rgb(${color})`;
    var contrast = darkness(color) ? "#202124" : "#fdfdfd";

    if (this.checked) {
      $radios.not(this).trigger("change");
      
      cancel.css("color", contrast);
      cancel.removeClass("off").addClass("on");
      dot.removeClass("on").addClass("off");

      tagbox.css({
        "background-color": rgb,
        color: contrast,
        "border-color": rgb,
        color: contrast
      });
    } else {
      cancel.removeClass("on").addClass("off");
      dot.removeClass("off").addClass("on");
      
      tagbox.css({
        "background-color": "#fff",
        color: "",
        "border-color": ""
      });
    }
  });

  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;
  }
});
/*input {
  display: none;
}*/

label {
  display: flex;
  align-items: center;
  font: 400 12px/16px Roboto Mono, monospace;
  letter-spacing: -0.2px;
  padding: 4px 0;
  user-select: none;
  cursor: pointer;
}

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

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

.text--tagbox {
  margin-right: 3px;
}

.cancel--tagbox {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 12px;
  height: 12px;
  margin-top: 3px;
  color: purple;
  transition: all 0.25s ease;
}

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

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

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

.dot.off,
.cancel--tagbox.off {
  width: 0px;
  height: 0px;
  opacity: 0;
}

.dot.on,
.cancel--tagbox.on {
  width: 12px;
  height: 12px;
  opacity: 1;
}

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

#i2+label .dot {
  background-color: rgb(0, 0, 255);
}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<button id="m_clear">Clear All</button>
<div class="tagboxes">
  <div class="tagbox">
    <input id="i0" type="radio" name="radio">
    <label data-rgb="255,64,129" for="i0">
    <mark style="background-color: rgb(255, 64, 129);" class="dot on"></mark>
    <b class='text--tagbox'>Lobster</b>
      <div class="cancel--tagbox off"><i class="fa fa-times"></i></div>
  </label>
  </div>
  <div class="tagbox">
    <input id="i1" type="radio" name="radio">
    <label data-rgb="49,231,182" for="i1">
    <mark class="dot on"></mark>
    <b class='text--tagbox'>Tuna</b>
    <div class="cancel--tagbox off"><i class="fa fa-times"></i></div>
  </label>
  </div>
  <div class="tagbox">
    <input id="i2" type="radio" name="radio">
    <label data-rgb="0,0,255" for="i2">
    <mark class="dot on"></mark>
    <b class='text--tagbox'>Pine</b>
    <div class="cancel--tagbox off"><i class="fa fa-times"></i></div>
  </label>
  </div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


推荐阅读