玩网络技术,我只使用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或更长时间)。但是,如果这样做,它是可以预测的(目标不是使其完美,而是至少模拟一些伪随机性)。
为什么会这样?我该怎么解决?
答案 0 :(得分:3)
正如您已经注意到的那样,问题出在动画的速度上。更改比单击要快,因为单击是两个动作:mousedown
和mouseup
,并且两者都应在同一元素上完成。
在这里可以更好地说明问题,您永远无法通过单击标签来检查输入:
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:active
和animation-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
上进行操作时从:hover
和label
之类的用户那里收到用户输入的。