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



利用web技术,我只使用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>

即使骰子滚动,当点击label时,它也不总是采取行动,并且与label相关的单选按钮未激活时,就会出现问题。有时是,有时不是。

我认为这可能是因为我使用的动画,并(没有成功(与时代一起玩,看看这是否能解决问题。。。但它基本上保持不变。我注意到,如果我延长时间,问题就会"消失"(即将时间更改为3秒,延迟0.5秒或更高(。但如果我这样做,它更容易预测(目标不是让它完美,而是至少模拟一些伪随机性(。

为什么会发生这种情况?我能做些什么来修复它?

正如您已经注意到的,问题是由于动画的速度有多快。更改比单击更快,因为单击是两个操作: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将不再位于同一元素上,因此单击事件不会完成。你的例子在某些情况下也是如此。


解决这个问题的一个想法是,通过将单击的元素放在顶部直到单击事件结束,来允许单击结束。

这里有一个想法,我依赖于一个具有大z-index的伪元素,这样我就可以在需要的元素上保留点击事件。您还可以使动画更快!

.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>

另一种方法是使用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>

当用户在相应的label上进行输入时,input实际上从:active:hover接收用户的输入。

最新更新