欢迎关注我的大众号:前端侦察
平时工作中许多场合都要用到定时器,比方推迟加载、定时查询等等,但定时器的操控有时候会有些许麻烦,比方鼠标移入中止、移出再重新开始。这次介绍几个凭借 CSS 来更好的操控定时器的方法,一同了解一下吧,信任能够带来不一样的体会
一、hover 延时触发
有这样一个场景,在鼠标停留在一个元素上1s
后才触发事情,不满1s
就不会触发,这样的优点是,能够避免鼠标在快速划过时,频繁的触发事情。假如是用js
来完成,或许会这样
var timer = null
el.addEventListener('mouseover', () => {
timer && clearTimeout(timer)
timer = setTimeout(() => {
// 详细逻辑
}, 1000)
})
是不是这样?等等,这样还没完,这样只做到了延时,鼠标脱离今后还是会触发,还需求在鼠标脱离时撤销定时器
el.addEventListener('mouseout', () => {
timer && clearTimeout(timer)
})
另外,在运用mouseout
时还需求考虑 dom
嵌套结构,由于这些事情在父级 -> 子级
的过程中仍然会触发,总之,细节会十分多,很简单误触发。
现在转机来了,假如借用 CSS 就能够有效地避免上述问题,如下,先给需求触发的元素加一个有延时的transition
button:hover{
opacity: 0.999; /*无关紧要的款式*/
transition: 0s 1s opacity; /*延时 1s */
}
这儿只需一个无关紧要的款式就行,假如opacity
现已运用过了,能够运用其他的,比方transform:translateZ(.1px)
,也是可行的。然后添加监听transitionend
方法
GlobalEventHandlers.ontransitionend – Web API 接口参阅 | MDN (mozilla.org)
el.addEventListener('transitionend', () => {
// 详细逻辑
})
这就结束了。无需定时器,也无需撤销,更无需考虑 dom
结构,完美完成。
下面是一个小实例,在hover
一段时间后触发alert
原理和上面一致,完整代码能够检查线上demo:hover_alert (codepen.io)或许hover_alert(runjs.work)
今后再碰到这样的需求能够停下来思考一番,许多和
mouseover
有关的交互都能够用这种方法来完成
二、长按触发事情
长按也是一个比较常见的需求,它能够很好的和点击事情区别开来,然后赋予更多的交互能力。
可是原生js
中却没有这样一个事情,假如要完成长按事情,一般需求凭借定时器和鼠标按下事情,如下
el.onmousedown = function(){
this.timer && clearTimeout(this.timer);
this.timer = settimeout(function(){
//业务代码
},1000)
}
el.onmouseup = function(){
this.timer && clearTimeout(this.timer);
}
又是定时器和撤销定时器的场景,和前面一个比如有些相似,也能够凭借 CSS 来完成,由所以鼠标按下,能够联想到:active
,因此能够这样来完成
button:hover:active{
opacity: .999; /*无关紧要的款式*/
transition: opacity 1s; /*延时 1s */
}
然后再监听transitionend
方法
el.addEventListener('transitionend', () => {
// 详细逻辑
})
是不是十分便利呢?下面是以前做过的一个小事例,完成了长按触发元素选中
完整代码能够检查线上demo:长按框选 (codepen.io)或许长按框选 (runjs.work)
三、轮播和暂停
再来看一个比较有意思的比如,轮播图。
一般轮播图都会自动播映,然后鼠标hover
时会暂停轮播图,一般的做法是这样的
function autoPlay(){
timer && clearInterval(timer)
timer = setInterval(function(){
// 轮播逻辑
}, 1000)
}
autoPlay()
view.onmouseover = function(){
timer && clearInterval(timer)
}
el.onmouseout = function(){
autoPlay()
}
又是定时器的撤销和设置,要绑定一堆事情,太烦人了,能够换种方法吗?当然能够了,凭借 CSS 动画,全部都好办了。
和前面不太相同的是,这儿是setInterval
,能够重复触发,那 CSS 中有什么能够重复触发的呢?没错,便是 CSS 动画!当 CSS 动画设置次数为infinite
就能够无限循环了,和这个定时器效果十分相似,而且能够直接经过:hover
暂停和播映动画。监听每次动画的触发能够用animationiteration
这个方法,表示每个动画轮回就触发一次
GlobalEventHandlers.onanimationiteration – Web API 接口参阅 | MDN (mozilla.org)
所以用这种思路完成便是
.view {
animation: scroll 1s infinite; /*每1s动画,无限循环*/
}
.view:hover{
animation-play-state: paused; /*hover暂停*/
}
@keyframes scroll {
to {
transform: translateZ(.1px); /*无关紧要的款式*/
}
}
然后再监听animationiteration
事情
view.addEventListener("animationiteration", () => {
// 轮播逻辑
})
是不是省去了大半的js
代码?而且也更好理解,操控也更为便利。
下面是一个经过animationiteration
来代替setInterval
完成的轮播图
完整代码能够检查线上demo:CSS banner(codepen.io)或许css_banner(runjs.work)
四、总结一下
以上便是你或许不需求定时器的几个代替计划,比较定时器而言,CSS 在操控定时器的开启和暂停上更有优势,下面总结一下
-
:hover
合作transition
延时、transitionend
监听能够完成鼠标经过延时触发效果 -
:active
合作transition
延时、transitionend
监听能够完成长按触发效果 - CSS 动画设置
infinite
后合作animationiteration
监听能够完成周期性触发效果 - 能够直接经过
:hover
来操控台动画的暂停和播映
当然,能够利用的不仅仅是以上几个事例,任何和 CSS 交互(:hover
、:active
)有相似功用的都能够朝这个方向去思考,是不是能够完成地更加高雅?
最终,假如觉得还不错,对你有帮助的话,欢迎点赞、收藏、转发❤❤❤
欢迎关注我的大众号:前端侦察