
本文旨在解决 CSS transition 在首次点击时无效,需要第二次点击才能生效的问题。通过分析问题代码,我们发现事件监听器被错误地放置在点击事件处理函数内部,导致监听器在第一次点击后才被绑定。本文将提供修改后的代码示例,确保 transition 效果在第一次点击时即可正常触发,并深入探讨事件监听器的正确使用方法。
问题分析
原始代码的问题在于,transitionEffect 函数内部绑定了 click 事件监听器。这意味着,只有在第一次点击 #last 按钮后,才会开始监听后续的点击事件。因此,transition 效果只能在第二次点击时生效。
function transitionEffect() {
const button = document.querySelector("#last");
button.addEventListener("click", function() {
var layers = document.querySelectorAll(".bottom-layer");
for (const layer of layers) {
setTimeout(switchVisible, 900);
layer.classList.toggle("active");
}
});
}解决方案
正确的做法是将事件监听器放在 transitionEffect 函数之外,确保在页面加载时就已绑定。同时,transitionEffect 函数本身应该只负责执行 transition 效果相关的操作。
以下是修改后的代码:
立即学习“前端免费学习笔记(深入)”;
function transitionEffect() {
var layers = document.querySelectorAll(".bottom-layer");
for (const layer of layers) {
setTimeout(switchVisible, 900);
layer.classList.toggle("active");
}
}
// 在页面加载后绑定事件监听器
document.addEventListener("DOMContentLoaded", function() {
const button = document.querySelector("#last");
button.addEventListener("click", transitionEffect);
});代码解释:
- transitionEffect 函数现在只负责切换 .bottom-layer 元素的 active 类,以及调用 switchVisible 函数。
- document.addEventListener("DOMContentLoaded", function() { ... }); 确保在页面完全加载后才执行其中的代码,避免在 DOM 元素尚未加载完成时尝试绑定事件监听器。
- 在 DOMContentLoaded 事件处理函数内部,我们获取 #last 按钮的引用,并使用 addEventListener 方法将 transitionEffect 函数绑定到按钮的 click 事件上。
完整示例代码
<!DOCTYPE html>
<html>
<head>
<title>CSS Transition Example</title>
<style>
#overlay-cont {
display: none;
z-index: 1;
}
.bottom-layer {
position: absolute;
width: 100%;
height: 100%;
top: 100%;
left: 0;
bottom: auto;
right: auto;
background: #48466d;
transition: all 0.7s cubic-bezier(0.645, 0.045, 0.355, 1);
}
.bottom-layer.active {
top: -100%;
}
.bottom-layer--2 {
background: #ecf3a3;
transition-delay: 0.12s;
}
.bottom-layer--3 {
background: #95a792;
transition-delay: 0.4s;
}
</style>
</head>
<body>
<button id="last">Click</button>
<div id="main-cont">
<h3>First Page</h3>
</div>
<div id="overlay-cont">
<div class="row">
<div class="col-md-6 overlay-text" id="overlay-col">
<h1>Next Page</h1>
</div>
<div class="col-md-6" id="overlay-col">
</div>
</div>
</div>
<div class="transition-cont">
<div class="bottom-layer"></div>
<div class="bottom-layer bottom-layer--2"></div>
<div class="bottom-layer bottom-layer--3"></div>
</div>
<script>
function transitionEffect() {
var layers = document.querySelectorAll(".bottom-layer");
for (const layer of layers) {
setTimeout(switchVisible, 900);
layer.classList.toggle("active");
}
}
function switchVisible() {
if (document.getElementById("main-cont")) {
if (document.getElementById("main-cont").style.display == "none") {
document.getElementById("main-cont").style.display = "block";
document.getElementById("overlay-cont").style.display = "none";
} else {
document.getElementById("main-cont").style.display = "none";
document.getElementById("overlay-cont").style.display = "block";
}
}
}
document.addEventListener("DOMContentLoaded", function() {
const button = document.querySelector("#last");
button.addEventListener("click", transitionEffect);
});
</script>
</body>
</html>注意事项:
- 确保 CSS transition 属性设置正确,包括 transition-property、transition-duration、transition-timing-function 和 transition-delay。
- 避免在 JavaScript 中直接操作元素的 style 属性,尽量通过添加或移除 CSS 类来触发 transition 效果。
- 使用 DOMContentLoaded 事件确保在 DOM 元素加载完成后再绑定事件监听器。
总结
正确地绑定事件监听器是确保 JavaScript 代码按预期执行的关键。通过将事件监听器放在 transitionEffect 函数之外,并在 DOMContentLoaded 事件触发后绑定,我们可以确保 CSS transition 效果在第一次点击时即可生效。 记住,理解事件循环和 DOM 加载时机对于编写高效、可靠的 JavaScript 代码至关重要。










