我的目的是使图像以滚动方式闪烁3次(例如依次亮起然后熄灭,以1秒的延迟连续闪烁3次),然后一直保持直到用户向下滚动超过3600像素为止。
我添加了事件监听器:
created() {
window.addEventListener('scroll', this.scrollAnimation)
}
在滚动时,我触发方法scrollAnimation
:
methods: {
scrollAnimation() {
let currentPos = window.pageYOffset
if (currentPos > 3000 && currentPos < 3600) {
this.$refs.supportOff.style.display = 'none'
this.$refs.supportOn.style.display = 'block'
} else {
this.$refs.supportOff.style.display = 'block'
this.$refs.supportOn.style.display = 'none'
}
}
}
这是图像的模板:
<div class="support__image-wrapper">
<img ref="supportOff" class="support__image support__image_on" src="../../assets/images/247-off.png">
<img ref="supportOn" class="support__image support__image_off" src="../../assets/images/247-on.png">
</div>
现在此代码有效,当我向下滚动3000像素但不低于3600像素时,它将显示247-on图像并隐藏247-off图像。但是,闪烁会出现问题,如果我使用setInterval
,则每当用户在3000至3600 px之间滚动时,都会触发该问题。实现闪烁的最佳方法是什么?
答案 0 :(得分:2)
一些尝试...
$ref
相反,创建一个变量,它在DOM
的变化触发methods: {
scrollAnimation() {
this.showSupport = window.pageYOffset > 3000 && window.pageYOffset < 3600
}
}
<div>
<img v-if="showSupport" class="blink" src="../../assets/images/247-on.png">
<img v-else src="../../assets/images/247-off.png">
</div>
@keyframes
)。这样,您就可以控制眨眼的时间,而不在脚本什么。它只是立即开始闪烁,因为它是在页面上可见。.blink {
animation: blink 1s infinite;
}
@keyframes blink {
0% {opacity: 0}
49%{opacity: 0}
50% {opacity: 1}
}
希望这会有所帮助。
答案 1 :(得分:1)
仅基于t3__rry's comment,为未优化/去抖动的基于滚动的事件如何导致严重的性能问题,为未来的读者添加一个快速演示;以及Mulhoon's nice advice,以及如何使用CSS @keyframes
来使动画闪烁:
new Vue({
el: '#app',
data() {
return {
blinkRate: 1000,
blinkCount: 3,
blinking: false,
blinkTimeoutId: -1,
state: false,
currentPos: window.pageYOffset
}
},
mounted() {
window.addEventListener('scroll', _.debounce(() => {
this.currentPos = window.pageYOffset;
if (this.currentPos > 3000 && this.currentPos < 3600) {
this.state = true;
}
else {
this.state = false;
}
}), 100);
},
methods: {
blink() {
if (this.blinkTimeoutId > -1) {
clearTimeout(this.blinkTimeoutId);
}
this.blinking = true;
this.blinkTimeoutId = setTimeout(() => {
this.blinking = false;
}, 1000 * this.blinkCount);
}
},
watch: {
state() {
this.blink();
}
}
});
#app {
background-color: gainsboro;
height: 2000vh;
padding: 10px;
}
.page-offset {
position: fixed;
top: 20px;
right: 20px;
}
.blinker > div {
border-radius: 50%;
border: 2px solid white;
color: white;
font-weight: bold;
height: 35px;
left: 20px;
line-height: 35px;
padding: 5px;
position: fixed;
text-align: center;
top: 20px;
vertical-align: middle;
width: 35px;
}
.blinker.animate > div {
animation: blink 1s infinite;
}
.blinker .on {
background-color: green;
}
.blinker .off {
background-color: crimson;
}
@keyframes blink {
0% {
opacity: 0
}
49% {
opacity: 0
}
50% {
opacity: 1
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
<div id="app">
<div :class="['blinker', { 'animate': blinking } ]">
<div class="on" v-if="state">ON</div>
<div class="off" v-else>OFF</div>
</div>
<code class="page-offset">pageYOffset: {{Math.floor(currentPos)}}</code>
</div>