解释我的问题的最好方法是下面两个演示:
就是它们:
演示1(在chrome中正常工作,在firefox中不起作用)
let handler = function () {
block.classList.add("visible");
requestAnimationFrame(() => block.classList.add("move"));
block.addEventListener(
"transitionend",
() => {
console.log("style is removed");
this.addEventListener("click", handler, { once: true });
block.classList.remove("move");
},
{ once: true }
);
};
btn.addEventListener("click", handler, { once: true });
.main {
display: none;
width: 100px;
height: 100px;
background: red;
transition: all 5.5s ease;
}
.visible {
display: block;
}
.move {
transform: translateX(100px);
background: blue;
}
<div id="block" class="main"></div>
<button id="btn">Animate</button>
演示2(工作不正确)
let handler = function () {
block.classList.add("visible");
block.classList.add("move");
block.addEventListener(
"transitionend",
() => {
console.log("style is removed");
this.addEventListener("click", handler, { once: true });
block.classList.remove("move");
},
{ once: true }
);
};
btn.addEventListener("click", handler, { once: true });
.main {
display: none;
width: 100px;
height: 100px;
background: red;
transition: all 5.5s ease;
}
.visible {
display: block;
}
.move {
transform: translateX(100px);
background: blue;
}
<div id="block" class="main"></div>
<button id="btn">Animate</button>
我将快速强调两个演示之间的差异:
- 第一个演示有requestAnimationFrame
-
<div>
block有class "visible"在第一个演示中启动点击处理程序之前 -
在click处理程序中,它有用于添加类"visible"在第二次演示
所以主要问题是:为什么第二个演示没有触发transitionend事件,为什么我没有看到过渡?
额外的演示
let handler = function () {
alert(1);
block.classList.add("visible");
alert(2);
setTimeout(() => {
alert(4);
block.classList.add("move");
alert(5);
});
block.addEventListener(
"transitionend",
() => {
console.log("style is removed");
this.addEventListener("click", handler, { once: true });
block.classList.remove("move");
},
{ once: true }
);
alert(3);
};
btn.addEventListener("click", handler, { once: true });
.main {
display: none;
width: 100px;
height: 100px;
background: red;
transition: all 5.5s ease;
}
.visible {
display: block;
}
.move {
transform: translateX(100px);
background: blue;
}
<div id="block" class="main"></div>
<button id="btn">Animate</button>
在chrome和firefox中检查它,似乎是代码的某些部分调用了重绘,如果不是,纠正我并解释为什么。
这里有几件事,你首先写的是block.classList.add("visible");
,我认为主要原因是你故意遗漏了这个class="main visible"
,因为你在代码中像class="main"
一样写它。
你实际上需要使用css样式技术,即使用none
来隐藏div和block
来显示它。这是我首先隐藏它的.visible { display: none; }
,然后显示它,我使用document.getElementById("block").style.display = "block";
。我添加了一个小延迟,给它一个时间来完成显示,然后开始动画工作,但不工作,如果你删除延迟。
let handler = function () {
//block.classList.add("visible");
document.getElementById("block").style.display = "block";
setTimeout(() => { block.classList.add("move"); }, 300);
//block.classList.add("move");
block.addEventListener(
"transitionend",
() => {
console.log("style is removed");
this.addEventListener("click", handler, { once: true });
block.classList.remove("move");
},
{ once: true }
);
};
btn.addEventListener("click", handler, { once: true });
.main {
display: none;
width: 100px;
height: 100px;
background: red;
transition: all 5.5s ease;
}
.visible {
display: none;
}
.move {
transform: translateX(100px);
background: blue;
}
<div id="block" class="main visible"></div>
<button id="btn">Animate</button>
所以要回答为什么它没有发射,这是由于我在上面解释的原因。