欢迎关注我的大众号:前端侦察

平时工作中许多场合都要用到定时器,比方推迟加载、定时查询等等,但定时器的操控有时候会有些许麻烦,比方鼠标移入中止、移出再重新开始。这次介绍几个凭借 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

还在用定时器吗?凭借 CSS 来监听事情

原理和上面一致,完整代码能够检查线上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', () => {
  // 详细逻辑
})

是不是十分便利呢?下面是以前做过的一个小事例,完成了长按触发元素选中

还在用定时器吗?凭借 CSS 来监听事情

完整代码能够检查线上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完成的轮播图

还在用定时器吗?凭借 CSS 来监听事情

完整代码能够检查线上demo:CSS banner(codepen.io)或许css_banner(runjs.work)

四、总结一下

以上便是你或许不需求定时器的几个代替计划,比较定时器而言,CSS 在操控定时器的开启和暂停上更有优势,下面总结一下

  1. :hover合作transition延时、transitionend监听能够完成鼠标经过延时触发效果
  2. :active合作transition延时、transitionend监听能够完成长按触发效果
  3. CSS 动画设置infinite后合作animationiteration监听能够完成周期性触发效果
  4. 能够直接经过:hover来操控台动画的暂停和播映

当然,能够利用的不仅仅是以上几个事例,任何和 CSS 交互(:hover:active)有相似功用的都能够朝这个方向去思考,是不是能够完成地更加高雅?

最终,假如觉得还不错,对你有帮助的话,欢迎点赞、收藏、转发❤❤❤

欢迎关注我的大众号:前端侦察