我想做的是有悬停过渡或动画(可以通过javascript与onmouseover
或onmouseenter
触发),这也将是可逆的(所以相反的动画应该发生在鼠标离开),但
- 相反的动画应该有一个延迟
- 它应该能够在动画中间无延迟地反转
不显示很难描述,所以请检查这个代码依存,这是非常接近我想要实现的:http://codepen.io/anon/pen/xROOqO
这里有两个问题:
- 我需要检查
transitionend
处理程序的运行时间,所以我需要更新css和js来更新过渡时间 - 当你快速悬停在反向动画上时,它仍然有延迟-看起来它被卡在中间
这甚至可能使用css过渡(也许关键帧动画),或者我应该坚持在javascript中设置计时器,并从css中删除延迟?
我不确定我将要呈现的内容是否更简单,但它似乎解决了您的一些问题,并且符合我的口味。
主要思想是承认问题由于多个状态而变得复杂,并使用状态机来解决它。这允许像这样的声明性方法:
const TRANSITIONS = {
'small-inside' : {
'transitionend' : 'big-inside',
'mouseover' : 'small-inside',
'mouseout' : 'small-outside',
},
'small-outside' : {
'transitionend' : 'small-outside',
'mouseover' : 'small-inside',
'mouseout' : 'small-outside',
},
'big-inside' : {
'transitionend' : 'big-inside',
'mouseover' : 'big-inside',
'mouseout' : 'big-outside',
},
'big-outside' : {
'transitionend' : 'small-outside',
'mouseover' : 'big-inside',
'mouseout' : 'big-outside',
},
}
和非常简单的事件处理:
function step(e){
box.className = TRANSITIONS[box.className][e.type];
}
box.addEventListener('transitionend', step);
box.addEventListener('mouseover', step);
box.addEventListener('mouseout', step);
另一个见解是,您可以使用CSS transition-delay:3s
属性指定延迟:
div.small-inside,
div.big-inside {
width: 300px;
}
div.small-outside,
div.big-outside {
width: 150px;
}
div.big-outside {
transition-delay:3s;
}
概念的证明在这里:http://codepen.io/anon/pen/pNNMWM.
我不喜欢我的解决方案是,它假设初始状态是small-outside
,而实际上,当页面加载时,鼠标指针可以很好地位于div内。您提到了从JS手动触发状态转换的能力。我相信这是可能的,只要你跟踪两个独立的布尔变量:"鼠标在里面吗?"one_answers"js要求增长吗?"。你不能把它们混合成一个状态,并期望正确的"计数"。正如你所看到的,我已经有了2*2=4
状态,因为我试图跟踪{small,big}x{inside,outside}
-人们可以想象以类似的方式将其扩展到{small,big}x{inside,outside}x{js-open,js-close}
,并添加一些额外的"事件",如"打开"one_answers"关闭"。