타이머는 로딩 지연, 예약된 쿼리 등 일상 업무에서 많은 상황에서 사용됩니다. 하지만 마우스를 안으로 움직여 정지했다가 다시 시작하는 등 타이머 제어가 약간 번거로울 때도 있습니다. . 이번에는 CSS의 도움으로 타이머를 더 잘 제어하는 몇 가지 방법을 소개하겠습니다. 이것이 다른 경험을 가져올 수 있다고 믿습니다. [추천 학습: css 동영상 튜토리얼]
마우스가 1s
요소에 머무른 후 이벤트가 트리거되는 시나리오가 있는데, 이는 불만족스럽습니다 1s
는 트리거되지 않습니다. 이것의 장점은 마우스가 빠르게 움직일 때 이벤트가 자주 트리거되는 것을 피할 수 있다는 것입니다. js
를 이용해서 구현하면 이런 모습이 나올 수도 있겠네요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
.view { animation: scroll 1s infinite; /*每1s动画,无限循环*/ } .view:hover{ animation-play-state: paused; /*hover暂停*/ } @keyframes scroll { to { transform: translateZ(.1px); /*无关紧要的样式*/ } }이렇지 않나요? 잠깐, 이건 아직 끝나지 않았습니다. 마우스가 떠난 후에도 여전히 트리거됩니다. 또한 마우스가 떠날 때 타이머를 취소해야 합니다.🎜
view.addEventListener("animationiteration", () => { // 轮播逻辑 })🎜또한
마우스아웃 이러한 이벤트는 <code>부모-> 하위
프로세스 중에 계속 발생하므로 dom
중첩 구조를 고려해야 합니다. 실수로 트리거하기 쉽습니다. 🎜🎜이제 전환점이 왔습니다. CSS를 빌리면 위의 문제를 효과적으로 피할 수 있습니다. 다음과 같이 먼저 트리거되어야 하는 요소에 지연된 전환
을 추가하세요.🎜rrreee🎜여기서만 필요합니다. 스타일은 중요하지 않습니다. opacity
가 이미 사용된 경우 transform:translateZ(.1px)
와 같은 다른 스타일을 사용할 수도 있습니다. 그런 다음 리스너 transitionend
메소드를 추가하세요🎜🎜GlobalEventHandlers.ontransitionend - 웹 API 인터페이스 참조 | MDN(mozilla.org)🎜🎜rrreee🎜끝입니다. 타이머도 없고, 취소도 없고,
dom
구조를 고려할 필요도 없고, 완벽한 구현입니다. 🎜🎜다음은 일정 시간 동안 hover
를 누른 후 alert
를 트리거하는 작은 예입니다🎜🎜🎜🎜원리는 위와 동일합니다. 전체 코드는 온라인 데모에서 볼 수 있습니다. : hover_alert(codepen.io)🎜또는 hover_alert(runjs.work)🎜🎜🎜? 앞으로 이런 필요가 생긴다면, 멈춰서 생각해 보세요. 대부분은 mouseover
와 유사합니다. 관련 상호작용은 이런 방식으로 실현될 수 있습니다🎜
js
에는 그런 이벤트가 없습니다. 길게 누르기 이벤트를 구현하려면 일반적으로 타이머와 마우스 누르기 이벤트를 사용해야 합니다. 다음은 타이머와입니다. 타이머를 취소합니다. 장면은 이전 예와 다소 유사하며 CSS를 사용하여 구현할 수도 있습니다. :active
와 연결할 수 있습니다. 이렇게 🎜rrreee🎜 구현하고 transitionend
를 들어보세요. 🎜rrreee🎜 방식이 참 편리하지 않나요? 다음은 내가 이전에 수행했던 작은 사례로, 요소 선택을 트리거하기 위해 길게 누르기를 구현했습니다🎜🎜🎜🎜전체 코드는 온라인 데모에서 볼 수 있습니다: 상자를 선택하려면 길게 누르세요(codepen.io)🎜또는 길게 눌러 상자 선택(runjs.work)🎜🎜hover
가 발생하면 캐러셀 이미지가 일시 정지됩니다. 일반적인 방법은 이렇습니다 🎜rrreee🎜타이머 취소 및 설정도 됩니다. 많은 바인딩이 필요합니다. 이벤트가 너무 짜증나서 다르게 할 수 있나요? 물론 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
)有类似功能的都可以朝这个方向去思考,是不是可以实现地更加优雅?
(学习视频分享:web前端)
위 내용은 CSS를 사용하여 타이머를 더 잘 제어하는 여러 가지 방법을 요약하고 공유합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!