问题
I have a set of tabs that each contain a child element that animates. What happens when I click each tab is that the animation of the child element within the tab runs. I do not want it to run. I want the animation to run the first time then not replay when it's parent switch from display:none
to display:block
.
In the example I made below I have 2 parent divs, each with a child div that animates over to the right. When each parent is set to block the animation replays, I do not want that to happen. I want each child to stay positioned over to the right. How can I make that happen?
$(".toggler").on("click", function() {
$(".parent").toggleClass("active");
});
.parent {
display: none;
cursor: pointer;
}
.child {
width: 100px;
height: 100px;
background-color: red;
position: relative;
animation: move 200ms cubic-bezier(.91, .8, .54, 1.39);
}
.active {
display: block;
}
.child.red {
background-color: red;
}
.child.blue {
background-color: blue;
}
@keyframes move {
from {
left: 0;
}
to {
left: 180px;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a class="toggler">Click this</a>
<div class="parent active">
<div class="child red"></div>
</div>
<div class="parent">
<div class="child blue"></div>
</div>
Fiddle Demo
回答1:
Yes, animations will restart every time the display
value is changed from none
to something else.
As per W3C Spec: (emphasis is mine)
Setting the display property to ‘none’ will terminate any running animation applied to the element and its descendants. If an element has a display of ‘none’, updating display to a value other than ‘none’ will start all animations applied to the element by the ‘animation-name’ property, as well as all animations applied to descendants with display other than ‘none’.
There is no direct way to prevent this from happening because that is the intended behavior. You can workaround the situation by using other methods to hide the element instead of using display: none
.
Following are a few suggestions on how the element could be hidden without display: none
. It is not mandatory to use only one of the following workarounds, it could be some other way also as long as it doesn't involve changing the display
property of the element.
Using
height: 0
,width: 0
,overflow: hidden
to hide the element.$(".toggler").on("click", function() { $(".parent").toggleClass("active"); });
.parent { height: 0; width: 0; overflow: hidden; cursor: pointer; } .child { width: 100px; height: 100px; background-color: red; position: relative; animation: move 200ms cubic-bezier(.91, .8, .54, 1.39) forwards; } .active { height: auto; width: auto; overflow: visible; } .child.red { background-color: red; } .child.blue { background-color: blue; } @keyframes move { from { left: 0; } to { left: 180px; } }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <a class="toggler">Click this</a> <div class="parent active"> <div class="child red"></div> </div> <div class="parent"> <div class="child blue"></div> </div>
Adding a container, using
position: absolute
andopacity: 0
to hide the element.$(".toggler").on("click", function() { $(".parent").toggleClass("active"); });
.container { position: relative; } .parent { position: absolute; opacity: 0; cursor: pointer; } .child { width: 100px; height: 100px; background-color: red; position: relative; animation: move 200ms cubic-bezier(.91, .8, .54, 1.39) forwards; } .active { opacity: 1; } .child.red { background-color: red; } .child.blue { background-color: blue; } @keyframes move { from { left: 0; } to { left: 180px; } }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <a class="toggler">Click this</a> <div class='container'> <div class="parent active"> <div class="child red"></div> </div> <div class="parent"> <div class="child blue"></div> </div> </div>
Adding a container, using
position: absolute
andvisibility: hidden
to hide the element.$(".toggler").on("click", function() { $(".parent").toggleClass("active"); });
.container { position: relative; } .parent { position: absolute; visibility: hidden; cursor: pointer; } .child { width: 100px; height: 100px; background-color: red; position: relative; animation: move 200ms cubic-bezier(.91, .8, .54, 1.39) forwards; } .active { visibility: visible; } .child.red { background-color: red; } .child.blue { background-color: blue; } @keyframes move { from { left: 0; } to { left: 180px; } }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <a class="toggler">Click this</a> <div class='container'> <div class="parent active"> <div class="child red"></div> </div> <div class="parent"> <div class="child blue"></div> </div> </div>
Adding a container, using
position: absolute
andz-index
to hide the element.$(".toggler").on("click", function() { $(".parent").toggleClass("active"); });
.container { position: relative; } .parent { position: absolute; z-index: -1; cursor: pointer; } .child { width: 100px; height: 100px; background-color: red; position: relative; animation: move 200ms cubic-bezier(.91, .8, .54, 1.39) forwards; } .active { z-index: 1; } .child.red { background-color: red; } .child.blue { background-color: blue; } @keyframes move { from { left: 0; } to { left: 180px; } }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <a class="toggler">Click this</a> <div class='container'> <div class="parent active"> <div class="child red"></div> </div> <div class="parent"> <div class="child blue"></div> </div> </div>
来源:https://stackoverflow.com/questions/37664508/stop-animation-from-replaying-when-parent-switches-from-displaynone-to-block