>웹 프론트엔드 >CSS 튜토리얼 >CSS를 사용하여 타이머를 더 잘 제어하는 ​​여러 가지 방법을 요약하고 공유합니다.

CSS를 사용하여 타이머를 더 잘 제어하는 ​​여러 가지 방법을 요약하고 공유합니다.

青灯夜游
青灯夜游앞으로
2022-09-16 11:21:222601검색

CSS를 사용하여 타이머를 더 잘 제어하는 ​​여러 가지 방법을 요약하고 공유합니다.

타이머는 로딩 지연, 예약된 쿼리 등 일상 업무에서 많은 상황에서 사용됩니다. 하지만 마우스를 안으로 움직여 정지했다가 다시 시작하는 등 타이머 제어가 약간 번거로울 때도 있습니다. . 이번에는 CSS의 도움으로 타이머를 더 잘 제어하는 ​​몇 가지 방법을 소개하겠습니다. 이것이 다른 경험을 가져올 수 있다고 믿습니다. [추천 학습: css 동영상 튜토리얼]

1. 호버 지연 트리거

마우스가 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

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', () => {
  // 具体逻辑
})

是不是非常方便呢?下面是以前做过的一个小案例,实现了长按触发元素选中

2 (1).gif

完整代码可以查看线上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를 트리거하는 작은 예입니다🎜🎜CSS를 사용하여 타이머를 더 잘 제어하는 ​​여러 가지 방법을 요약하고 공유합니다.🎜🎜원리는 위와 동일합니다. 전체 코드는 온라인 데모에서 볼 수 있습니다. : hover_alert(codepen.io)🎜또는 hover_alert(runjs.work)🎜🎜
🎜? 앞으로 이런 필요가 생긴다면, 멈춰서 생각해 보세요. 대부분은 mouseover와 유사합니다. 관련 상호작용은 이런 방식으로 실현될 수 있습니다🎜

2. 누르기 트리거 이벤트🎜🎜길게 누르는 것도 비교적 일반적인 요구 사항이므로 클릭 이벤트와 잘 구별되어 더 많은 대화형 기능을 제공할 수 있습니다. 🎜🎜하지만 네이티브 js에는 그런 이벤트가 없습니다. 길게 누르기 이벤트를 구현하려면 일반적으로 타이머와 마우스 누르기 이벤트를 사용해야 합니다. 다음은 타이머와입니다. 타이머를 취소합니다. 장면은 이전 예와 다소 유사하며 CSS를 사용하여 구현할 수도 있습니다. :active와 연결할 수 있습니다. 이렇게 🎜rrreee🎜 구현하고 transitionend를 들어보세요. 🎜rrreee🎜 방식이 참 편리하지 않나요? 다음은 내가 이전에 수행했던 작은 사례로, 요소 선택을 트리거하기 위해 길게 누르기를 구현했습니다🎜🎜2 (1).gif🎜🎜전체 코드는 온라인 데모에서 볼 수 있습니다: 상자를 선택하려면 길게 누르세요(codepen.io)🎜또는 길게 눌러 상자 선택(runjs.work)🎜🎜

3. 캐러셀 그리고 일시정지🎜🎜좀 더 흥미로운 예인 캐러셀 차트를 살펴보겠습니다. 🎜🎜보통 캐러셀 이미지가 자동으로 재생되다가 마우스 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实现的轮播图

CSS를 사용하여 타이머를 더 잘 제어하는 ​​여러 가지 방법을 요약하고 공유합니다.

完整代码可以查看线上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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제