CSS Animation onClick
Are you sure you only display your page on webkit? Here is the code, passed on safari.
The image (id='img')
will rotate after button click.
function ani() {
document.getElementById('img').className = 'classname';
}
.classname {
-webkit-animation-name: cssAnimation;
-webkit-animation-duration: 3s;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: ease;
-webkit-animation-fill-mode: forwards;
}
@-webkit-keyframes cssAnimation {
from {
-webkit-transform: rotate(0deg) scale(1) skew(0deg) translate(100px);
}
to {
-webkit-transform: rotate(0deg) scale(2) skew(0deg) translate(100px);
}
}
<input name="" type="button" onclick="ani()" value="Click">
<img id="img" src="https://i.stack.imgur.com/vghKS.png" width="328" height="328" />
Trigger CSS Animation on Click via javascript
A bit ugly, because of the extra class needed, but it works:
var hamburgerMenu = document.querySelector('.hamburger-menu');
hamburgerMenu.addEventListener('click', function() {
var hamburgerMenuSpan2 = document.querySelector('.hamburger-second');
if (hamburgerMenuSpan2.classList.contains("animate-out")) {
hamburgerMenuSpan2.classList.remove("animate-out");
hamburgerMenuSpan2.classList.add("animate-in");
} else {
hamburgerMenuSpan2.classList.add("animate-out");
hamburgerMenuSpan2.classList.remove("animate-in");
}
});
.hamburger-menu {
position: absolute;
top: 20px;
right: 20px;
}
.hamburger-line-2 {
animation-duration: 3s;
animation-timing-function: ease-in-out;
animation-fill-mode: forwards;
animation-direction: alternate;
}
.animate-out {
animation-name: animate-out;
}
.animate-in {
animation-name: animate-in;
}
@keyframes animate-out {
0% {
width: 40px;
}
100% {
width: 0px;
}
}
@keyframes animate-in {
0% {
width: 0px;
}
100% {
width: 40px;
}
}
.hamburger-menu span {
display: block;
width: 40px;
height: 2px;
background: black;
margin: 10px 0px;
}
<div class="hamburger-menu">
<span class="hamburger-line-1"></span>
<span class="hamburger-second hamburger-line-2"></span>
<span class="hamburger-line-3"></span>
</div>
Trigger CSS Animation on div click
Note that in your code, the elements that have "animation" css rules are the LI elements. So changing the animation property of the UL's style won't work.
Here I changed your CSS a bit so that you can give the UL the class of "animate" and the child LIs will animate. When you press the button it removes that class, and then using a setTimeout re-adds it, it should reset and replay the animation.
document.getElementById("clickable").addEventListener("click", controlAnimation);
function controlAnimation() {
const menu = document.querySelector('#menu-main-menu');
menu.classList.remove('animate');
setTimeout(() => {
menu.classList.add('animate');
}, 0);
}
#menu-main-menu li {
border-bottom: solid 1px #999;
}
#menu-main-menu.animate li {
opacity: 0;
-webkit-animation: fadeInMenu 0.5s 1;
animation: fadeInMenu 0.5s 1;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
#menu-main-menu.animate li:nth-child(5n+1) {
-webkit-animation-delay: 0.1s;
animation-delay: 0.1s;
}
#menu-main-menu.animate li:nth-child(5n+2) {
-webkit-animation-delay: 0.3s;
animation-delay: 0.3s;
}
#menu-main-menu.animate li:nth-child(5n+3) {
-webkit-animation-delay: 0.5s;
animation-delay: 0.5s;
}
#menu-main-menu.animate li:nth-child(5n+4) {
-webkit-animation-delay: 0.7s;
animation-delay: 0.7s;
}
#menu-main-menu.animate li:nth-child(5n+5) {
-webkit-animation-delay: 0.9s;
animation-delay: 0.9s;
}
/* Animation steps */
@-webkit-keyframes fadeInMenu {
0% {
opacity: 0.0;
transform: translateY(16px);
}
100% {
opacity: 1.0;
}
}
@keyframes fadeInMenu {
0% {
opacity: 0.0;
transform: translateY(16px);
}
100% {
opacity: 1.0;
}
<div id="clickable" >Click me</div>
<br>
<ul id="menu-main-menu" class='animate'>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
I can make an div fade in onclick, but how do i make it fade out?
Easier approach using jQuery animation, no CSS animation
function scrollToAccept() {
const terms = document.querySelector('.terms-and-conditions');
const button = document.querySelector('.accept');
// const watch = document.querySelector('.watch');
if (!terms) {
return; // quit function because there is no terms
}
// fires on page load because can't find element
function obCallback(payload) {
// console.log(payload[0].isIntersecting); // whether element is in view or not
// console.log(payload[0].intersectionRatio); // how much of the element is showing
if (payload[0].intersectionRatio === 1) {
button.disabled = false;
// stop observing the last element
ob.unobserve(terms.lastElementChild);
}
}
// takes in callback parameter
// will be called every time it needs to check if something is currently on the page
// watcher (needs to be told what to watch
const ob = new IntersectionObserver(obCallback, {
root: terms,
threshold: 1,
});
// call observe method on what we want to watch
// ob.observe(watch);
ob.observe(terms.lastElementChild);
}
scrollToAccept();
$('.yes').on('click', function(e) {
e.preventDefault();
$('.TOSHIDE').fadeToggle(3000).toggleClass('active');
//$(this).parents('ul').next().toggleClass('active');
});
body {
background: #ffffff;
}
.wrapper-all {
min-height: 94vh;
display: grid;
justify-content: center;
align-content: center;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
line-height: 2;
}
.wrapper {
width: 400px;
height: 80vh;
padding: 20px;
border: 1px solid black;
background: white;
display: grid;
grid-template-rows: 1fr auto;
}
button {
background: #133C55;
color: white;
font-size: 1rem;
padding: 20px;
transition: opacity 0.2s;
}
button[disabled] {
opacity: 0.1;
/* transform: translateX(-300%) scale(0.5); */
}
.terms-and-conditions {
overflow: scroll;
}
footer {
background-color: #192718;
width: 100%;
padding: 8px 0;
margin-top: 8px;
}
footer .container {
width: 800px;
margin: 0 auto;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
justify-content: space-between;
align-items: flex-start;
}
footer .container a {
color: #fff;
}
footer a:hover {
color: #fce26a;
}
.tacbox {
display: block;
padding: 1em;
margin: 2em;
border: 3px solid #ddd;
background-color: #eee;
max-width: 800px;
}
input {
height: 2em;
width: 2em;
vertical-align: middle;
}
.TOSHIDE {
display: none;
}
.TOSHIDE.active {
display: block;
opacity: 1;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Terms of Service</title>
<link rel="stylesheet" href="./scroll-to-accept.css" />
<link rel="stylesheet" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
</head>
<body>
<script>
function unhideTOS() {
document.getElementById("text").style.display = "";
}
</script>
<script>
function unlockBTN() {
document.getElementById("text").style.display = "";
}
</script>
<div class="tacbox">
<!-- The code for the checkbox + download if checked. -->
I agree to these <a href="#tos" class="yes">Terms and Conditions.</a>
<br>
<a id="text" style="display:none" href="file.doc" Download>Download!</a>
</div>
<div class="TOSHIDE">
<div class="wrapper-all">
<div class="wrapper">
<div class="terms-and-conditions">
<h1>Terms and Conditions</h1>
<p>Disclaimer THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. You are the Current Maintainer of the Software, and to permit recipients of the Licensed Product for any such warranty, support,
indemnity or liability obligations to one or more recipients of Covered Code. However, You may do so in a commercial product offering.</p>
<hr>
</div>
<button class="accept" disabled autocomplete="off" id="myCheck" onclick="unlockBTN()">Accept</button>
</div>
</div>
</div>
<script src="./scroll-to-accept.js"></script>
</body>
</html>
How to synchronize CSS animations that were started/restarted at different times
For this purpose document.getAnimations()
is a useful method. It returns an array of all animation objects currently in effect whose target elements are descendants of the document. More information: https://developer.mozilla.org/en-US/docs/Web/API/Document/getAnimations
Items of document.getAnimations()
include currentTime
property, that can use for syncing animations. More information: https://drafts.csswg.org/web-animations/#dom-documentorshadowroot-getanimations
toggleFx
function was modified and now it has three parts.
In the first part, search document.getAnimations()
and find currentTime
attribute where animationName
is one of pulse_active
or pulse_inverted
; then store them in the realted variables (i.e. pulseActiveStart
and pulseInvertedStart
).
In the 2nd part, className
of spanTarget
changed as you told.
In the 3rd part, pulseActiveStart
and pulseInvertedStart
applied to currentTime
attribute of related animation (reverse 1st part).
function toggleFx(spanID) {
let spanTarget = document.getElementById(spanID);
let pulseActiveStart;
let pulseInvertedStart;
let anims = document.getAnimations()
for(let i = 0; i < anims.length; i++) {
if(anims[i].animationName == "pulse_active") pulseActiveStart = anims[i].currentTime;
else if(anims[i].animationName == "pulse_inverted") pulseInvertedStart = anims[i].currentTime;
}
if(spanTarget.classList.contains('pulse_invert')) {
spanTarget.classList.remove('pulse_invert');
spanTarget.classList.remove('pulse');
} else if(spanTarget.classList.contains('pulse')) {
spanTarget.classList.add('pulse_invert');
spanTarget.classList.remove('pulse');
} else {
spanTarget.classList.add('pulse');
}
anims = document.getAnimations()
for(let i = 0; i < anims.length; i++) {
if(anims[i].animationName == "pulse_active") {
if(pulseActiveStart) anims[i].currentTime = pulseActiveStart;
} else if(anims[i].animationName == "pulse_inverted") {
if(pulseInvertedStart) anims[i].currentTime = pulseInvertedStart;
}
}
}
div {
display: flex;
flex-flow: column;
}
span.pulse {
color: #f00;
animation: pulse_active 1.5s ease-in infinite;
}
span.pulse_invert {
color: #00f;
animation: pulse_inverted 3s ease-in infinite;
}
@keyframes pulse_active {
0% { opacity: 0; }
50% { opacity: 0.66; }
100% { opacity: 0; }
}
@keyframes pulse_inverted {
0% { opacity: 1; }
50% { opacity: 0.33; }
100% { opacity: 1; }
}
<div>
<span id="spA" onclick="toggleFx('spA')">A</span>
<span id="spB" onclick="toggleFx('spB')">B</span>
<span id="spC" onclick="toggleFx('spC')">C</span>
<span id="spD" onclick="toggleFx('spD')">D</span>
</div>
css animation-play-state on click
You can use the ~
to change properties of changing css of the element's sibling.
Assuming you want to totally do it in css, you can't really make the button play & pause at the same time, you can use JS for a single button.
I have done it using 2 buttons here, one button for playing & one for pausing.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<button class="button" id="play">play</button>
<button class="button" id="pause">pause</button>
<div id="stage"></div>
</body>
</html>
CSS
#stage{
height:300px;
border:1px solid #000;
overflow: hidden;
animation: stage-change 6s 6 forwards;
animation-play-state: paused;
}
@keyframes stage-change {
0% {
background-color: darkorange ;
}
100% {
background-color: #1c1341;
}
}
#play:focus ~ #stage{
animation-play-state: running;
}
#pause:focus ~ #stage{
animation-play-state: paused;
}
OR
You can use the checkbox hack, if you really just want to use one input element to control the animation.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<input type="checkbox" id="check"> play
<div id="stage"></div>
</body>
</html>
CSS
#stage{
height:300px;
border:1px solid #000;
overflow: hidden;
animation: stage-change 6s 6 forwards;
animation-play-state: paused;
}
@keyframes stage-change {
0% {
background-color: darkorange ;
}
100% {
background-color: #1c1341;
}
}
#play:checked ~ #stage{
animation-play-state: running;
}
How to start css animation on click and run the animation reversed on second click?
If you really want to make this reversible animation, I suggest you to use transition
instead of keyframes
, since when you start the animation
, there's no way to keep track the current state and the target state, so if you click the button while the animation is unfinished, it'll jump directly to the last frame and play reverse.
But still, here's the solution:
const demo = document.querySelector('.demo');
const button = document.querySelector('button');
let reverse = false;
button.addEventListener('click', onClickPlay);
function onClickPlay(){
// Save the animation state
let animation = demo.style.animation;
// Clear the animation
demo.style.animation = 'none';
// You need to call this at next draw call to make the animation take effects
setTimeout(()=>{
// Restore the animation
demo.style.animation = animation;
// Make the animation running
demo.style.animationPlayState = 'running';
// Set the animation direction by current state
demo.style.animationDirection = reverse ? 'reverse' : 'normal';
// Flip the state
reverse = !reverse;
button.innerText = reverse ? 'Reverse' : 'Forward';
}, 0);
}
@keyframes anim {
0% {
width: 0px;
background-color: red;
}
100% {
width: 100px;
background-color: blue;
}
}
.demo {
/* Make the animation paused at the beginning */
animation: anim 1s paused both;
width: 0px;
height: 20px;
}
<button>Forward</button>
<div class="demo"><div>
CSS Animations Onclick
I think it should be
document.getElementById("s1_imgB").className += " shake";
Related Topics
Best Way to Find If an Item Is in a JavaScript Array
How to Find the Operating System Details Using JavaScript
How to Handle Newlines in Json
Regex to Extract All Matches from String Using Regexp.Exec
How to Show a Running Progress Bar While Page Is Loading
Simulate Background-Size:Cover on <Video> or <Img>
Visibility:Hidden VS Display:None VS Opacity:0
Webkit and Jquery Draggable Jumping
Better Way to Prevent Browser Caching of JavaScript Files
Prevent Address-Bar Hiding in Mobile Browsers
Modify a CSS Rule Object with JavaScript
Get Computed Font-Family in JavaScript
Read :Hover Pseudo Class with JavaScript
Html5 Video - Percentage Loaded
How to Use JavaScript Conditionally Like CSS3 Media Queries, Orientation
How to Convert a Comma-Separated String to an Array
Get the Real Width and Height of an Image With JavaScript? (In Safari/Chrome)