javascript - 单击不同的单选按钮后取消选中单选按钮

标签 javascript html css

我正在制作一个带有两个按钮(赞成票/反对票)的投票系统。我已经使用 input 和 label 标签来创建它,但是有一个问题:

如果我使用单选按钮,我可以投赞成票或反对票,但不能取消投票。

如果我使用复选框,我可以取消投票,但我也可以投赞成票和反对票。

我想要实现的是能够只投赞成票或反对票,同时也能够取消投票(想想 reddit)。

我彻底寻找了一个答案,但我发现这不可能用 CSS 来完成。那里有很多脚本,问题是我不了解 JavaScript 或 jQuery,所以我不知道如何实现代码。

我认为最简单的解决方案是在我点击赞成票时取消选中反对票按钮,反之亦然,但同样,我不知道这段代码会是什么样子或如何实现它。

也许有一个更简单的解决方案,即使用纯 CSS 更改另一个按钮的外观,即使它已被选中?我不知道,但如果存在这样的解决方案,我宁愿使用它。

我的代码:

input[type=radio] {
  display: none
}
#up {
  width: 20px;
  height: 16px;
  background: url(http://c.thumbs.redditmedia.com/Y5Gt7Gtk59BlV-3t.png) left top;
  position: absolute;
  left: 50px;
  top: 50px
}
#down {
  width: 20px;
  height: 16px;
  background: url(http://c.thumbs.redditmedia.com/Y5Gt7Gtk59BlV-3t.png) left bottom;
  opacity: 0.5;
  position: absolute;
  left: 50px;
  top: 84px
}
#vote {
  width: 21px;
  height: 18px;
  text-align: center;
  font-size: 26px;
  line-height: 18px;
  position: absolute;
  left: 50px;
  top: 66px;
  z-index: -1
}
#up:hover {
  background-position: top;
  cursor: pointer
}
#upvote:checked ~ #up {
  background-position: top;
}
#upvote:checked ~ #vote {
  color: #DC5B28;
  z-index: 1
}
#down:hover {
  background-position: bottom;
  cursor: pointer;
  opacity: 1
}
#downvote:checked ~ #down {
  background-position: bottom;
  opacity: 1
}
#downvote:checked ~ #vote {
  color: #3580DD
}
#no {
  position: absolute;
  display: none;
  background: url(http://c.thumbs.redditmedia.com/Y5Gt7Gtk59BlV-3t.png)
}
#upvote:checked ~ #no {
  display: block;
  background-position: left top;
  left: 50px;
  top: 50px
}
#downvote:checked ~ #no {
  display: block;
  background-position: left bottom;
  left: 50px;
  top: 84px;
  opacity: 0.5
}
<input type="radio" name="vote" value="+1" id="upvote">
<label for="upvote" id="up"></label>
<input type="radio" name="vote" value="-1" id="downvote">
<label for="downvote" id="down"></label>
<input type="radio" name="vote" value="0" id="novote">
<label for="novote" id="no"></label>
<div id="vote">•</div>

最佳答案

如果你想要一个纯 CSS 的解决方案,你可以尝试添加一个默认隐藏的第三个选项,它代表没有投票。

然后,当用户投赞成票或反对票时,会显示第三个选项,它与所选选项重叠。

因此,当用户认为他再次点击所选选项时,他实际上是在选择不投票选项。

#vote {
  position: relative;
}
#vote > input {
  display: none;                    /* Hide radio buttons */
}
#vote > label {
  cursor: pointer;
  display: block;
  width: 0;
  border: 50px solid;               /* We will make them look like... */
  border-color: black transparent;  /* ...triangles using borders */
}
#upvote + label {                   
  border-top: none;                 /* Triangulating */
}
#downvote + label {                 
  border-bottom: none;              /* Triangulating */
  margin-top: 15px;                 /* Space between triangles */
}
#vote > input:checked + label {     
  border-color: orange transparent; /* Highlight chosen option */
}
#vote > #novote-label { 
  display: none;                    /* Hide it by default */
  position: absolute;               /* Take it out of the normal flow */
  border-top: none;
  border-color: transparent;
}
#upvote:checked ~ #novote-label {   /* Display it overlapping upvote */
  display: block;
  top: 0;
}
#downvote:checked ~ #novote-label { /* Display it overlapping downvote */
  display: block;
  bottom: 0;
}
<div id="vote">
  <input type="radio" name="vote" value="+1" id="upvote" />
  <label for="upvote"></label>
  <input type="radio" name="vote" value="-1" id="downvote" />
  <label for="downvote"></label>
  <input type="radio" name="vote" value="0" id="novote" />
  <label for="novote" id="novote-label"></label>
</div>

只需稍作改动,它也可以通过键盘访问:

#vote {
  position: relative;
}
#vote > input {                      /* Hiding in a keyboard-accesible way */
  opacity: 0;
  position: absolute;
  z-index: -1;
}
#vote > input:focus + label {
  outline: 1px dotted #999;          /* Keyboard friendly */
}
#vote > label {
  cursor: pointer;
  display: block;
  width: 0;
  border: 50px solid;               /* We will make them look like... */
  border-color: black transparent;  /* ...triangles using borders */
}
#upvote + label {                   
  border-top: none;                 /* Triangulating */
}
#downvote + label {                 
  border-bottom: none;              /* Triangulating */
  margin-top: 15px;                 /* Space between triangles */
}
#vote > input:checked + label {     
  border-color: orange transparent; /* Highlight chosen option */
}
#vote > #novote-label { 
  display: none;                    /* Hide it by default */
  position: absolute;               /* Take it out of the normal flow */
  border-top: none;
  border-color: transparent;
}
#upvote:checked ~ #novote-label {   /* Display it overlapping upvote */
  display: block;
  top: 0;
}
#downvote:checked ~ #novote-label { /* Display it overlapping downvote */
  display: block;
  bottom: 0;
}
<div id="vote">
  <input type="radio" name="vote" value="+1" id="upvote" />
  <label for="upvote"></label>
  <input type="radio" name="vote" value="-1" id="downvote" />
  <label for="downvote"></label>
  <input type="radio" name="vote" value="0" id="novote" />
  <label for="novote" id="novote-label"></label>
</div>

上面的代码片段使用边框来模拟三 Angular 形/箭头。同样,也可以使用背景图片。

#vote {
    position: relative;
}
#vote > input {
    display: none;
}
#vote > label {
    cursor: pointer;
    display: block;
    width: 20px;
    height: 16px;
    background-image: url('http://i.stack.imgur.com/36F2b.png');
}
#vote > #up {
    background-position: left top;
}
#vote > #down {
    background-position: left bottom;
}
#upvote:checked ~ #up {
    background-position: top;
}
#downvote:checked ~ #down {
    background-position: bottom;
}
#vote > #no {
    display: none;
    position: absolute;
    background: none;
}
#upvote:checked ~ #no {
    display: block;
    top: 0;
}
#downvote:checked ~ #no {
    display: block;
    bottom: 0;
}
<div id="vote">
    <input type="radio" name="vote" value="+1" id="upvote" />
    <label for="upvote" id="up"></label>
    <input type="radio" name="vote" value="-1" id="downvote" />
    <label for="downvote" id="down"></label>
    <input type="radio" name="vote" value="0" id="novote" />
    <label for="novote" id="no"></label>
</div>

关于javascript - 单击不同的单选按钮后取消选中单选按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27727781/

相关文章:

javascript - 平滑滚动效果在 Mozilla 和 IE 中不起作用?

html - 高宽过渡原点

html - 使用css设置元素的最大宽度

javascript - 无法绑定(bind) ngModel,因为它不是 "Component"的属性

javascript - 可折叠侧边栏.....想要修复侧边栏的页眉和页 footer 分

javascript - 当另一个面板打开时关闭 Accordion 面板

javascript - Firefox 和 Google Chrome 中 location.reload() 的不同行为

javascript - 为什么我不能让我的表单关闭,以便我可以访问导航栏?

javascript - 使用 contentEditable div 而不是 textarea 有什么缺点?

javascript - 简单的 jQuery 自定义向导表单