当动画的一部分时,标签不会激活关联的字段

时间:2018-07-20 20:13:16

标签: html css html5 css3 css-animations

玩网络技术,我只使用HTML和CSS(没有JavaScript)开发了一个骰子。这是一个简单的系统:一系列单选按钮和标签,它们通过更改其位置(使用z-index来模拟骰子,因此每次单击骰子时,都会有一个“随机”数字。

这是代码的最低版本:

@keyframes changeOrder {
  from { z-index: 6;}
  to { z-index: 1; }
}

@-webkit-keyframes changeOrder {
  from { z-index: 6; }
  to { z-index: 1; }
}

label {
  display: block;
  position: absolute;
  display: block;
  width: 50px;
  height: 50px;
  line-height:50px;
  background: #eeeeee;
  text-align: center;
  animation: changeOrder 1.2s infinite;
}

label:nth-of-type(1) { animation-delay: 0s; }
label:nth-of-type(2) { animation-delay: -0.2s; }
label:nth-of-type(3) { animation-delay: -0.4s; }
label:nth-of-type(4) { animation-delay: -0.6s; }
label:nth-of-type(5) { animation-delay: -0.8s; }
label:nth-of-type(6) { animation-delay: -1.0s; }
<input type="radio" name="cb" id="cb1" value="1"/>
<input type="radio" name="cb" id="cb2" value="2"/>
<input type="radio" name="cb" id="cb3" value="3"/>
<input type="radio" name="cb" id="cb4" value="4"/>
<input type="radio" name="cb" id="cb5" value="5"/>
<input type="radio" name="cb" id="cb6" value="6"/>
<label for="cb1">1</label>
<label for="cb2">2</label>
<label for="cb3">3</label>
<label for="cb4">4</label>
<label for="cb5">5</label>
<label for="cb6">6</label>

即使骰子为 rolling ,当单击label并与label关联的单选按钮时,并非总是采取措施时,就会发生问题未激活。有时确实如此,有时却没有。

我认为可能是因为我使用了动画,并且(不成功地)与时俱进,看是否能解决问题……但是基本上保持不变。我注意到,如果我延长时间,问题就会“消失”(即,将时间更改为3s,并延迟0.5s或更长时间)。但是,如果这样做,它是可以预测的(目标不是使其完美,而是至少模拟一些伪随机性)。

为什么会这样?我该怎么解决?

2 个答案:

答案 0 :(得分:3)

正如您已经注意到的那样,问题出在动画的速度上。更改比单击要快,因为单击是两个动作:mousedownmouseup,并且两者都应在同一元素上完成。

在这里可以更好地说明问题,您永远无法通过单击标签来检查输入:

label {
  display: block;
  position: absolute;
  display: block;
  width: 50px;
  height: 50px;
  line-height:50px;
  background: #eeeeee;
  text-align: center;
}

label:active {
  background:red;
  z-index:-1;
}
<input type="radio" name="cb" id="cb1" value="1">
<input type="radio" name="cb" id="cb2" value="2">
<label for="cb1">1</label>
<label for="cb2">2</label>

单击时,该元素将被隐藏,mouseup将不再位于同一元素上,因此click事件不会完成。在某些情况下,您的示例也会发生同样的情况。


解决此问题的一种方法是允许点击结束,方法是将被点击的元素放在顶部,直到点击事件结束。

这里是一个我依赖于z-index大的伪元素的想法,因此我可以将click事件保留在所需的元素上。您还可以使动画更快!

.container {
 position:relative;
}
label {
  display:block;
  position: absolute;
  top:0;
  left:0;
  width: 50px;
  height: 50px;
  line-height:50px;
  background: #eeeeee;
  text-align: center;
  animation: changeOrder 0.6s infinite;
}
@keyframes changeOrder {
  from { z-index: 6;}
  to { z-index: 1; }
}
label:nth-of-type(1) { animation-delay: 0s; }
label:nth-of-type(2) { animation-delay: -0.1s; }
label:nth-of-type(3) { animation-delay: -0.2s; }
label:nth-of-type(4) { animation-delay: -0.3s; }
label:nth-of-type(5) { animation-delay: -0.4s; }
label:nth-of-type(6) { animation-delay: -0.5s; }

label:active {
  /*Mandatory to break the stacking context and allow 
   the pseudo element to be above everything*/
  position:static; 
  /*For illustration*/
  margin-left: 50px;
  background:red;
}

label:active::before {
  content:"";
  position:absolute;
  top:0;
  right:0;
  left:0;
  bottom:0;
  z-index:10;
}
<input type="radio" name="cb" id="cb1" value="1">
<input type="radio" name="cb" id="cb2" value="2">
<input type="radio" name="cb" id="cb3" value="3">
<input type="radio" name="cb" id="cb4" value="4">
<input type="radio" name="cb" id="cb5" value="5">
<input type="radio" name="cb" id="cb6" value="6">
<div class="container"> 
 <label for="cb1">1</label>
 <label for="cb2">2</label>
 <label for="cb3">3</label>
 <label for="cb4">4</label>
 <label for="cb5">5</label>
 <label for="cb6">6</label>
</div>

答案 1 :(得分:0)

另一种方法是使用input:activeanimation-play-state: paused,如下所示:

@keyframes changeOrder {
  from { z-index: 6;}
  to { z-index: 1; }
}

@-webkit-keyframes changeOrder {
  from { z-index: 6; }
  to { z-index: 1; }
}

label {
  display: block;
  position: absolute;
  display: block;
  width: 50px;
  height: 50px;
  line-height:50px;
  background: #eeeeee;
  text-align: center;
  animation: changeOrder 1.2s infinite;
}

label:nth-of-type(1) { animation-delay: 0s; }
label:nth-of-type(2) { animation-delay: -0.2s; }
label:nth-of-type(3) { animation-delay: -0.4s; }
label:nth-of-type(4) { animation-delay: -0.6s; }
label:nth-of-type(5) { animation-delay: -0.8s; }
label:nth-of-type(6) { animation-delay: -1.0s; }

input:active ~ label {
  animation-play-state: paused;
}
<input type="radio" name="cb" id="cb1" value="1"/>
<input type="radio" name="cb" id="cb2" value="2"/>
<input type="radio" name="cb" id="cb3" value="3"/>
<input type="radio" name="cb" id="cb4" value="4"/>
<input type="radio" name="cb" id="cb5" value="5"/>
<input type="radio" name="cb" id="cb6" value="6"/>
<label for="cb1">1</label>
<label for="cb2">2</label>
<label for="cb3">3</label>
<label for="cb4">4</label>
<label for="cb5">5</label>
<label for="cb6">6</label>

这是因为input实际上是在用户在相应的:active上进行操作时从:hoverlabel之类的用户那里收到用户输入的。