Css 单击下拉菜单时关键帧动画不透明度会闪烁
Css Keyframe animation opacity get flashing when click on dropdown menu
在多次尝试添加不透明度的简单进/出动画后,我得到了我想要的结果。但是,动画会导致不必要的闪烁。
如果您从一个项目切换到另一个项目,您会注意到内容会闪烁片刻。我做错了什么?
此外,是否有一种“更简洁”且更短的方法可以达到相同的效果?
var dropdownBtn = document.querySelectorAll('.menu-btn');
dropdownBtn.forEach(btn => btn.addEventListener('click', function() {
var menuContent = this.nextElementSibling;
closeMenusExcept(menuContent);
if (!menuContent.classList.contains("show")) {
menuContent.classList.add("show");
} else {
menuContent.classList.add("hide");
setTimeout(function(){
menuContent.classList.remove("show");
menuContent.classList.remove("hide");
},100)
}
}));
function closeMenusExcept(menuContent) {
dropdownBtn.forEach((element) => {
if (menuContent !== element.nextElementSibling) {
element.nextElementSibling.classList.remove("show");
element.nextElementSibling.classList.add("hide");
}
})
}
.menu-btn {
background: #e0e0e0;
padding: 10px;
margin: 5px 0px 0px 0px;
}
.menu-btn:hover {
background: #000;
color: #fff;
}
.drop_container {
display: none;
background-color: #fff;
animation:animateFromBottom 0.3s
}
.drop_container.show {
display: block;
}
.drop_container.hide {
animation:animateToBottom 0.3s;
}
.drop_container > .item {
display: flex;
flex-direction: column;
margin-left: 10px;
padding: 10px 0px 0px 0px;
}
@keyframes animateFromBottom {
from{opacity:0}
to{opacity:1}
}
@keyframes animateToBottom {
from{opacity:1}
to{opacity:0}
}
<div class="dropdown-menu">
<div class="menu-btn">One</div>
<div class="drop_container">
<a class="item" href="#">Contact Us</a>
<a class="item" href="#">Visit Us</a>
</div>
<div class="menu-btn">Two</div>
<div class="drop_container">
<a class="item" href="#">Contact Us</a>
<a class="item" href="#">Visit Us</a>
</div>
</div>
您需要将不透明度换成 max-height,这是您的解决方案:https://codepen.io/nitinsuri/pen/bGLrLQB
var dropdownBtn = document.querySelectorAll('.menu-btn');
dropdownBtn.forEach(btn => btn.addEventListener('click', function() {
var menuContent = this.nextElementSibling;
closeMenusExcept(menuContent);
if (!menuContent.classList.contains("show")) {
menuContent.classList.add("show");
} else {
menuContent.classList.add("hide");
setTimeout(function(){
menuContent.classList.remove("show");
menuContent.classList.remove("hide");
},100)
}
}));
function closeMenusExcept(menuContent) {
dropdownBtn.forEach((element) => {
if (menuContent !== element.nextElementSibling) {
element.nextElementSibling.classList.remove("show");
element.nextElementSibling.classList.add("hide");
}
})
}
.menu-btn {
background: #e0e0e0;
padding: 10px;
margin: 5px 0px 0px 0px;
}
.menu-btn:hover {
background: #000;
color: #fff;
}
.drop_container {
background-color: #fff;
max-height: 0;
overflow: hidden;
}
.drop_container.show {
max-height: 100vh;
animation:animateFromBottom 1s;
}
.drop_container > .item {
display: flex;
flex-direction: column;
margin-left: 10px;
padding: 10px 0px 0px 0px;
}
@keyframes animateFromBottom {
from{
max-height: 0;
overflow: hidden;}
to{max-height: 100vh;}
}
@keyframes animateToBottom {
from{max-height: 100vh;}
to{
max-height: 0;
overflow: hidden;}
}
<div class="dropdown-menu">
<div class="menu-btn">One</div>
<div class="drop_container">
<a class="item" href="#">fist link of One</a>
<a class="item" href="#">second link of One</a>
</div>
<div class="menu-btn">Two</div>
<div class="drop_container">
<a class="item" href="#">fist link of Two</a>
<a class="item" href="#">second link of Two</a>
</div>
</div>
在Jquery中你可以这样处理。您可以根据需要使用切换或滑动切换来放慢或放快。我刚刚添加了一些新的 class,因此您的 css 不会受到影响。如果这是您正在查看的内容,请告诉我。
$(document).ready(function(){
$(".btn1").click(function(){
$(".container1").slideToggle();
$(".container2").hide("slow");
});
$(".btn2").click(function(){
$(".container2").slideToggle();
$(".container1").hide("slow");
});
});
.menu-btn {
background: #e0e0e0;
padding: 10px;
margin: 5px 0px 0px 0px;
}
.menu-btn:hover {
background: #000;
color: #fff;
}
.drop_container {
display: none;
background-color: #fff;
animation:animateFromBottom 0.3s
}
.drop_container.show {
display: block;
}
.drop_container.hide {
animation:animateToBottom 0.3s;
}
.drop_container > .item {
display: flex;
flex-direction: column;
margin-left: 10px;
padding: 10px 0px 0px 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="dropdown-menu">
<div class="menu-btn btn1">One</div>
<div class="drop_container container1">
<a class="item" href="#">Contact Us</a>
<a class="item" href="#">Visit Us</a>
</div>
<div class="menu-btn btn2">Two</div>
<div class="drop_container container2">
<a class="item" href="#">Contact Us</a>
<a class="item" href="#">Visit Us</a>
</div>
</div>
在多次尝试添加不透明度的简单进/出动画后,我得到了我想要的结果。但是,动画会导致不必要的闪烁。
如果您从一个项目切换到另一个项目,您会注意到内容会闪烁片刻。我做错了什么?
此外,是否有一种“更简洁”且更短的方法可以达到相同的效果?
var dropdownBtn = document.querySelectorAll('.menu-btn');
dropdownBtn.forEach(btn => btn.addEventListener('click', function() {
var menuContent = this.nextElementSibling;
closeMenusExcept(menuContent);
if (!menuContent.classList.contains("show")) {
menuContent.classList.add("show");
} else {
menuContent.classList.add("hide");
setTimeout(function(){
menuContent.classList.remove("show");
menuContent.classList.remove("hide");
},100)
}
}));
function closeMenusExcept(menuContent) {
dropdownBtn.forEach((element) => {
if (menuContent !== element.nextElementSibling) {
element.nextElementSibling.classList.remove("show");
element.nextElementSibling.classList.add("hide");
}
})
}
.menu-btn {
background: #e0e0e0;
padding: 10px;
margin: 5px 0px 0px 0px;
}
.menu-btn:hover {
background: #000;
color: #fff;
}
.drop_container {
display: none;
background-color: #fff;
animation:animateFromBottom 0.3s
}
.drop_container.show {
display: block;
}
.drop_container.hide {
animation:animateToBottom 0.3s;
}
.drop_container > .item {
display: flex;
flex-direction: column;
margin-left: 10px;
padding: 10px 0px 0px 0px;
}
@keyframes animateFromBottom {
from{opacity:0}
to{opacity:1}
}
@keyframes animateToBottom {
from{opacity:1}
to{opacity:0}
}
<div class="dropdown-menu">
<div class="menu-btn">One</div>
<div class="drop_container">
<a class="item" href="#">Contact Us</a>
<a class="item" href="#">Visit Us</a>
</div>
<div class="menu-btn">Two</div>
<div class="drop_container">
<a class="item" href="#">Contact Us</a>
<a class="item" href="#">Visit Us</a>
</div>
</div>
您需要将不透明度换成 max-height,这是您的解决方案:https://codepen.io/nitinsuri/pen/bGLrLQB
var dropdownBtn = document.querySelectorAll('.menu-btn');
dropdownBtn.forEach(btn => btn.addEventListener('click', function() {
var menuContent = this.nextElementSibling;
closeMenusExcept(menuContent);
if (!menuContent.classList.contains("show")) {
menuContent.classList.add("show");
} else {
menuContent.classList.add("hide");
setTimeout(function(){
menuContent.classList.remove("show");
menuContent.classList.remove("hide");
},100)
}
}));
function closeMenusExcept(menuContent) {
dropdownBtn.forEach((element) => {
if (menuContent !== element.nextElementSibling) {
element.nextElementSibling.classList.remove("show");
element.nextElementSibling.classList.add("hide");
}
})
}
.menu-btn {
background: #e0e0e0;
padding: 10px;
margin: 5px 0px 0px 0px;
}
.menu-btn:hover {
background: #000;
color: #fff;
}
.drop_container {
background-color: #fff;
max-height: 0;
overflow: hidden;
}
.drop_container.show {
max-height: 100vh;
animation:animateFromBottom 1s;
}
.drop_container > .item {
display: flex;
flex-direction: column;
margin-left: 10px;
padding: 10px 0px 0px 0px;
}
@keyframes animateFromBottom {
from{
max-height: 0;
overflow: hidden;}
to{max-height: 100vh;}
}
@keyframes animateToBottom {
from{max-height: 100vh;}
to{
max-height: 0;
overflow: hidden;}
}
<div class="dropdown-menu">
<div class="menu-btn">One</div>
<div class="drop_container">
<a class="item" href="#">fist link of One</a>
<a class="item" href="#">second link of One</a>
</div>
<div class="menu-btn">Two</div>
<div class="drop_container">
<a class="item" href="#">fist link of Two</a>
<a class="item" href="#">second link of Two</a>
</div>
</div>
在Jquery中你可以这样处理。您可以根据需要使用切换或滑动切换来放慢或放快。我刚刚添加了一些新的 class,因此您的 css 不会受到影响。如果这是您正在查看的内容,请告诉我。
$(document).ready(function(){
$(".btn1").click(function(){
$(".container1").slideToggle();
$(".container2").hide("slow");
});
$(".btn2").click(function(){
$(".container2").slideToggle();
$(".container1").hide("slow");
});
});
.menu-btn {
background: #e0e0e0;
padding: 10px;
margin: 5px 0px 0px 0px;
}
.menu-btn:hover {
background: #000;
color: #fff;
}
.drop_container {
display: none;
background-color: #fff;
animation:animateFromBottom 0.3s
}
.drop_container.show {
display: block;
}
.drop_container.hide {
animation:animateToBottom 0.3s;
}
.drop_container > .item {
display: flex;
flex-direction: column;
margin-left: 10px;
padding: 10px 0px 0px 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="dropdown-menu">
<div class="menu-btn btn1">One</div>
<div class="drop_container container1">
<a class="item" href="#">Contact Us</a>
<a class="item" href="#">Visit Us</a>
</div>
<div class="menu-btn btn2">Two</div>
<div class="drop_container container2">
<a class="item" href="#">Contact Us</a>
<a class="item" href="#">Visit Us</a>
</div>
</div>