gpt4 book ai didi

javascript - 取消 for 循环中多个元素的挂起 setTimeouts

转载 作者:太空宇宙 更新时间:2023-11-04 00:50:05 25 4
gpt4 key购买 nike

我正在尝试创建一个很酷的小微交互,但我遇到了一个小问题。

document.querySelector('button').onclick = function(){
const
items = document.querySelector('nav').children
if (items[0].getBoundingClientRect().top >= document.querySelector('nav').getBoundingClientRect().bottom){
// start showing elements, starting from the left side
for (let i = 0; i < items.length; i++){
setTimeout(function(){
items[i].style.transform = 'translateY(0)'
}, i * 200)
}
} else {
// start hiding elements, starting from the right side
for (let i = 0; i < items.length; i++){
setTimeout(function(){
items[i].style.transform = 'translateY(100%)'
}, (items.length-1 - i) * 200)
}
}
}
button {
width: 100px;
height: 50px;
}

nav {
width: 50vw;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 10px;
background: red;
}

nav > a {
width: 100%;
height: 50px;
transition: .5s transform;
transform: translateY(100%);
opacity: 0.5;
background: lime;
}
<button>Toggle</button>
<nav>
<a href=''></a>
<a href=''></a>
<a href=''></a>
<a href=''></a>
</nav>

如果您连续切换得太快,一些元素最终会显示,而其他元素最终会被隐藏。

这是因为在发出新的 setTimeouts 集时,还有未决的 setTimeouts 尚未执行。

显然有一些方法可以解决这个问题,比如不颠倒动画的顺序,等到动画完全完成后再允许颠倒等等,但我宁愿不做出这样的妥协。

我尝试在 ifelse block 中使用和切换全局 bool 值,然后使用额外的 if/else 语句在 setTimeout block 中,但这没有用。

我还尝试在应用新的 transform 值之前即时设置 transition 延迟,而不是依赖于 setTimeout,这并没有工作。

有没有一种简单的方法可以取消或忽略来自周期的任何未决setTimeouts

最佳答案

我会简化你的逻辑并考虑 transition-delay 你只需要切换一个类。诀窍是当我们切换类以获得所需效果时,为您的元素设置不同的延迟。

使用此配置,您不会有任何问题,因为所有元素都将具有相同的状态,因为类已添加到它们的父元素。

var nav = document.querySelector('nav');
document.querySelector('button').onclick = function(){
nav.classList.toggle('top');
}
button {
width: 100px;
height: 50px;
}

nav {
width: 50vw;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 10px;
background: red;
--d:0.2s;
}

nav > a {
width: 100%;
height: 50px;
transition: .5s transform;
transform: translateY(100%);
opacity: 0.5;
background: lime;
}
nav.top > a {
transform: translateY(0);
}

nav > a:nth-last-child(1) { transition-delay:calc(0 * var(--d));}
nav > a:nth-last-child(2) { transition-delay:calc(1 * var(--d));}
nav > a:nth-last-child(3) { transition-delay:calc(2 * var(--d));}
nav > a:nth-last-child(4) { transition-delay:calc(3 * var(--d));}

nav.top > a:nth-child(1) { transition-delay:calc(0 * var(--d));}
nav.top > a:nth-child(2) { transition-delay:calc(1 * var(--d));}
nav.top > a:nth-child(3) { transition-delay:calc(2 * var(--d));}
nav.top > a:nth-child(4) { transition-delay:calc(3 * var(--d));}
<button>Toggle</button>
<nav>
<a href=''></a>
<a href=''></a>
<a href=''></a>
<a href=''></a>
</nav>

我们可以通过将具有相同延迟的元素分组来简化 CSS 代码:

var nav = document.querySelector('nav');
document.querySelector('button').onclick = function(){
nav.classList.toggle('top');
}
button {
width: 100px;
height: 50px;
}

nav {
width: 50vw;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 10px;
background: red;
--d:0.2s;
}

nav > a {
width: 100%;
height: 50px;
transition: .5s transform;
transform: translateY(100%);
opacity: 0.5;
background: lime;
}
nav.top > a {
transform: translateY(0);
}

nav > a:nth-last-child(1),
nav.top > a:nth-child(1) { transition-delay:calc(0 * var(--d));}

nav > a:nth-last-child(2),
nav.top > a:nth-child(2) { transition-delay:calc(1 * var(--d));}

nav > a:nth-last-child(3),
nav.top > a:nth-child(3){ transition-delay:calc(2 * var(--d));}

nav > a:nth-last-child(4),
nav.top > a:nth-child(4){ transition-delay:calc(3 * var(--d));}
<button>Toggle</button>
<nav>
<a href=''></a>
<a href=''></a>
<a href=''></a>
<a href=''></a>
</nav>

关于javascript - 取消 for 循环中多个元素的挂起 setTimeouts,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56139497/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com