Welcome to my public account: front-end detective
In daily work, timers are used in many occasions, such as delayed loading, timed query, etc., but the control of timers is sometimes a little troublesome, such as mouse move in to stop, move out and start again. This time, I will introduce a few methods to better control the timer with CSS. Let’s learn about it together. I believe it can bring a different experience.
1. Hover delay trigger
There is such a scene, when the mouse hovers on an element 1s
, the event will be triggered, and the dissatisfaction 1s
will not trigger. Frequent trigger events. If it is implemented with js
, it may be like this
var timer = null
el.addEventListener('mouseover', () => {
timer && clearTimeout(timer)
timer = setTimeout(() => {
// 具体逻辑
}, 1000)
})
is this correct? Wait, this is not over yet, this is only a delay, it will still be triggered after the mouse leaves, and the timer needs to be canceled when the mouse leaves
el.addEventListener('mouseout', () => {
timer && clearTimeout(timer)
})
In addition, when using mouseout
also need to consider the dom
nested structure , because these events will still fire in the process of 父级 -> 子级
, in short, there will be a lot of details , it is easy to trigger by mistake.
Now the turning point is coming. If you borrow CSS, you can effectively avoid the above problems. As follows, first add a delay to the element that needs to be triggered transition
button:hover{
opacity: 0.999; /*无关紧要的样式*/
transition: 0s 1s opacity; /*延时 1s */
}
Only one insignificant style is needed here. If opacity
has been used, it is possible to use other ones, such as transform:translateZ(.1px)
, which is also feasible. Then add the listener transitionend
method
GlobalEventHandlers.ontransitionend - Web API Interface Reference | MDN (mozilla.org)
el.addEventListener('transitionend', () => {
// 具体逻辑
})
This is the end of it. No timer, no cancellation, and no need to consider dom
structure, perfect realization.
The following is a small example, after hover
is triggered after a period of time alert
The principle is the same as above, the complete code can be viewed online demo: hover_alert(runjs.work)
🤔If you encounter such a need in the future, you can stop and think about it. Many interactions related to mouseover
can be implemented in this way.
2. Long press trigger event
Long press is also a relatively common requirement, which can be well differentiated from click events, thus giving more interactive capabilities.
However, there is no such event in the native js
. If you want to implement a long press event, you usually need to use a timer and a mouse press event, as follows
el.onmousedown = function(){
this.timer && clearTimeout(this.timer);
this.timer = settimeout(function(){
//业务代码
},1000)
}
el.onmouseup = function(){
this.timer && clearTimeout(this.timer);
}
It is a timer and a timer cancellation scenario, which is similar to the previous example, and can also be implemented with CSS. Since it is a mouse press, it can be associated with :active
, so it can be implemented in this way
button:hover:active{
opacity: .999; /*无关紧要的样式*/
transition: opacity 1s; /*延时 1s */
}
Then listen again transitionend
method
el.addEventListener('transitionend', () => {
// 具体逻辑
})
Is it very convenient? The following is a small case that has been done before, which realizes long-press trigger element selection
The complete code can be viewed online demo: long press the box to select (runjs.work)
3. Carousel and Pause
Let’s look at a more interesting example, the carousel.
Usually the carousel will play automatically, and then the mouse hover
will pause the carousel. The usual practice is like this
function autoPlay(){
timer && clearInterval(timer)
timer = setInterval(function(){
// 轮播逻辑
}, 1000)
}
autoPlay()
view.onmouseover = function(){
timer && clearInterval(timer)
}
el.onmouseout = function(){
autoPlay()
}
It is the cancellation and setting of the timer again. It is too annoying to bind a bunch of events. Can you change it? Of course you can, with CSS animations, everything is easy to do.
Different from the previous one, here is setInterval
, which can be triggered repeatedly, so what can be repeatedly triggered in CSS? That's right, CSS animations !
When the number of CSS animation settings is infinite
, it can loop infinitely, which is very similar to this timer effect, and can directly pause and play the animation through :hover
. To monitor the trigger of each animation, you can use animationiteration
this method, which means that each animation is triggered once
GlobalEventHandlers.onanimationiteration - Web API Interface Reference | MDN (mozilla.org)
So implementing this way of thinking is
.view {
animation: scroll 1s infinite; /*每1s动画,无限循环*/
}
.view:hover{
animation-play-state: paused; /*hover暂停*/
}
@keyframes scroll {
to {
transform: translateZ(.1px); /*无关紧要的样式*/
}
}
Then listen for animationiteration
event
view.addEventListener("animationiteration", () => {
// 轮播逻辑
})
Did you leave out most of the js
code? It is also easier to understand and control.
The following is a carousel implemented by animationiteration
instead of setInterval
The complete code can be viewed online demo: css_banner(runjs.work)
Fourth, to summarize
The above are a few alternatives where you may not need a timer. Compared with timers, CSS has more advantages in controlling the start and pause of timers. Let's summarize
-
:hover
cooperate withtransition
delay,transitionend
monitoring can realize mouse trigger effect after delay -
:active
withtransition
delay,transitionend
monitor can achieve long-press trigger effect - CSS animation settings
infinite
post-couplinganimationiteration
monitoring can achieve periodic triggering effect - The console animation can be paused and played directly through
:hover
Of course, not only the above cases can be used, anyone who interacts with CSS ( :hover
, :active
) with similar functions can think in this direction, is it possible to achieve more elegant? 🤔
Finally, if you think it's good and helpful to you, please like, bookmark, and forward ❤❤❤
Welcome to my public account: front-end detective
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。