gpt4 book ai didi

Javascript 添加/删除动画类,只动画一次

转载 作者:行者123 更新时间:2023-11-30 09:11:48 25 4
gpt4 key购买 nike

尝试构建一个时间选择器,它应该为输入的变化设置动画。我想我会通过在 CSS 中添加和删除动画类来做到这一点。问题是,它只在第一次起作用。

我尝试设置一个间隔开始,在一定时间后删除类,略高于动画持续时间,但每次点击都会减少动画的动画时间,第三次或第四次点击,它不再动画。

然后我只是选择检查该类是否存在,首先删除它,然后添加它。以确保它每次都从头开始。但现在它只在第一次动画。

Codepen

HTML:


<div id="wrapper">
<div id="uphour"></div>
<div id="upminute"></div>
<div id="upampm"></div>
<div class="animated">
<div id="hour" data-hour="1">2</div>
</div>
<div class="animated">
<div id="minute" data-minute="1">50</div>
</div>
<div class="animated">
<div id="ampm" data-minute="AM">AM</div>
</div>
<div id="downhour"></div>
<div id="downminute"></div>
<div id="downampm"></div>
</div>

(这里的数据属性暂时没有使用)

SCSS:


$finger: 2cm;
$smallfinger: .3cm;

#wrapper {
display: grid;
grid-template-columns: $finger $finger $finger;
grid-template-rows: $finger $finger $finger;
grid-column-gap: $smallfinger;
grid-row-gap: $smallfinger;
position:absolute;
width: 100vw;
background: #FF00FF;
height: calc( (#{$finger} * 3) + (#{$smallfinger} * 4) );
box-sizing: border-box;
bottom:$finger;
left:0;
padding:0;
margin:0;
align-content: center;
justify-content: center;
}

#uphour,
#upminute,
#upampm,
#downhour,
#downminute,
#downampm {
display: flex;
background: rgba(255,0,0,.4);
width: $finger;
height: $finger;
margin-left: 1vw;
margin-right: 1vw;
border: 1px solid black;
}

.animated {
display: flex;
width: $finger;
height: $finger;
margin-left: 1vw;
margin-right: 1vw;
border: 1px solid black;
overflow:hidden;
}


#minute, #hour, #ampm {
display: flex;
/*background: rgba(255,0,0,.4); for testing of animation only*/
width: $finger;
height: $finger;
border: 0;
position: relative;
align-items: center;
justify-content: center;
font-size: .8cm;
}

.animateStart {
-webkit-animation-name: downandout; /* Safari 4.0 - 8.0 */
animation-name: downandout;
-webkit-animation-duration: 250ms; /* Safari 4.0 - 8.0 */
animation-duration: 250ms;
/*-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;*/
transition-timing-function: cubic-bezier(1,0,0,1);
}

/* Safari 4.0 - 8.0 */
@-webkit-keyframes downandout {
0% {top: 0; left: 0;}
10% {top: 100%; left:0;}
50% {top: 100%; left: 100%;}
90% {top: -100%; left:100%;}
}

/* Standard syntax */
@keyframes downandout {
0% {top: 0; left: 0;}
40% {top: 100%; left:0;}
42% {top: 100%; left: calc(#{$finger} * 2);}
48% {top: -110%; left: calc(#{$finger} * 2);}
50% {top: -110%; left:0;}
100% {top: 0; left:0;}
}

Javascript:


var uphourEl = document.getElementById("uphour");
var downhourEl = document.getElementById("downhour");
var upminuteEl = document.getElementById("upminute");
var downminuteEl = document.getElementById("downminute");
var upampmEl = document.getElementById("upampm");
var downampmEl = document.getElementById("downampm");

uphourEl.addEventListener("click", increaseHour);
downhourEl.addEventListener("click", decreaseHour);
upminuteEl.addEventListener("click", increaseMinute);
downminuteEl.addEventListener("click", decreaseMinute);
upampmEl.addEventListener("click", swapAMPM);
downampmEl.addEventListener("click", swapAMPM);

var hourEl = document.getElementById("hour");
var minuteEl = document.getElementById("minute");
var ampmEl = document.getElementById("ampm");

function increaseHour() {
let value = hourEl.innerHTML;
if (value > 11) {
value = 1
} else {
value++;
}
hourEl.innerHTML = value;
console.log(value);
}

function decreaseHour() {
let value = hourEl.innerHTML;
if (value < 2) {
value = 12
} else {
value--;
}
hourEl.innerHTML = value;
console.log(value);
}

function increaseMinute() {
let value = minuteEl.innerHTML;
if (value > 58) {
value = 0
} else {
value++;
}
minuteEl.innerHTML = value;
console.log(value);
}

function decreaseMinute() {
let value = minuteEl.innerHTML;
if (value < 1) {
value = 59
} else {
value--;
}
minuteEl.innerHTML = value;
console.log(value);
}

function swapAMPM() {
let value = ampmEl.innerHTML;
if (ampmEl.hasAttribute("class")) {
ampmEl.removeAttribute("class");
}
ampmEl.setAttribute("class", "animateStart");
if (value === "AM") {
value = "PM";
ampmEl.innerHTML = value;
console.log("Changed from AM");
} else {
value = "AM";
ampmEl.innerHTML = value;
console.log("Changed from PM");
}
}

..它是 swapAMPM 函数(在 Javascript 的末尾),我目前无法按预期运行。

关于我为什么会遇到这种行为的任何建议?我缺少一些最佳实践吗?

最佳答案

您可以使用动画迭代事件监听器来检测动画何时结束,并正确删除您的类。为此,必须将动画迭代设置为无限。在我的更改中,我还利用元素的 classList 属性从元素中添加/删除类。

注意:如果没有至少 1 次迭代,动画迭代事件将永远不会触发,因此代码将无法运行!

编辑:浏览器对 classList 的支持是相当新的,因此如果您需要支持旧版浏览器,您可以回退到不同的解决方案,或添加 classList polyfill

首先,我们需要一个函数来检测浏览器支持哪个动画迭代事件:

function whichAnimationEvent(){
var el = document.createElement("fakeelement");

var animations = {
"animation" : "animationiteration",
"OAnimation" : "oAnimationIteration",
"MozAnimation" : "animationiteration",
"WebkitAnimation": "webkitAnimationIteration"
};

for (let t in animations){
if (el.style[t] !== undefined){
return animations[t];
}
}
}

接下来,我们需要为该事件添加一个事件监听器,当迭代触发时,我们从元素的 classList 中删除该类,如下所示:

ampmEl.addEventListener(whichAnimationEvent(),function(){
console.log('ampmEl event listener fired')
ampmEl.classList.remove('animateStart');
});

接下来,我们更改swapAMPM函数,使用元素classListadd方法在执行之前添加类交换,使其具有动画效果。

function swapAMPM() {
let value = ampmEl.innerHTML;
ampmEl.classList.add('animateStart');
if (value === "AM") {
value = "PM";
ampmEl.innerHTML = value;
console.log("Changed from AM");
} else {
value = "AM";
ampmEl.innerHTML = value;
console.log("Changed from PM");
}
}

最后,我们需要更新 css 以具有无限 动画迭代,这样我们的事件就会触发。

.animateStart {
-webkit-animation-name: downandout; /* Safari 4.0 - 8.0 */
animation-name: downandout;
-webkit-animation-duration: 250ms; /* Safari 4.0 - 8.0 */
animation-duration: 250ms;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
transition-timing-function: cubic-bezier(1,0,0,1);
}

完整的工作示例

codepen

关于Javascript 添加/删除动画类,只动画一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58170892/

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