I have a form with save and reset buttons. And I have a button icon on the top of the form. I am trying to make the button icon bounce when a user clicks the save button. I don't want to use the jQuery UI. I already gave it a try but I just want to use the plain CSS and a simple onclick javascript function to make this work.
Here is the bounce CSS I am using:
.bounce{
position: relative;
-webkit-animation: bounce 1s 5;
}
#-webkit-keyframes bounce{
0%{
bottom:5px;
}
25%, 75%{
bottom: 15px;
}
50%{
bottom: 20px;
}
100%{
bottom: 0;
}
}
The Css works pretty well, but obviously it bounces when the page is loaded as I have added the class="bounce" to the button icon.
<button class="container-list bounce" data-toggle="modal" data-target="#container-modal"><img src="images/container-rack.png"></button>
I have a very long form, and at the end, I have the button container as following which has the save and reset buttons.
<div class="container-buttons">
<button class="btn btn-success" id="save_container" type="submit">Save</button>
<button class="btn btn-warning" type="reset">Reset</button>
</div>
So, how can I trigger the bounce css property, whenever the save button is clicked? Please help me. :)
You have to add the class when the button is clicked. By removing the class after 1 second (or however long your animation is), you can add it again with the same button.
Now, I don't see your jQuery or anything, so I'm just going to put some generic jQuery here:
$('#save_container').click(function () {
var b = $('.container-list');
b.addClass('bounce');
setTimeout(function () {
b.removeClass('bounce');;
}, 1000);
});
When the #save_container is clicked, .container-list will get the class .bounce and remove it after 1 second (since my animation in the fiddle is 1 second long).
JSFIDDLE
Answer 2
As per Anthony Grist's suggestion, you could flip the operations around and with that get it to work with every single click.
That solution can be found in this fiddle and the jQuery looks like this:
$('#save_container').click(function (e) {
var b = $('button.container-list');
b.removeClass('bounce');
window.setTimeout(function() {
b.addClass('bounce');
}, 1);
});
In this code, the .bounce class gets removed and 1ms after that it gets added again. In the 2nd fiddle $('.container-list') contains button as well, but that's only because the HTML is a bit different.
The reason why you should go for answer two is that it can be triggered over and over again, without you having to wait for the class to be removed first.
Credit for answer 2 goes to #AnthonyGrist!
Remove the .button class from the element and add it on when the user clicks the button:
var button = document.querySelector("button");
button.onclick = function() {
var secondButton = document.querySelector("#second-button");
secondButton.classList.remove("bounce");
secondButton.offsetWidth = secondButton .offsetWidth;
secondButton.classList.add("bounce");
};
.bounce {
position: relative;
-webkit-animation: bounce 1s 5;
}
#-webkit-keyframes bounce {
0% {
bottom: 5px;
}
25%,
75% {
bottom: 15px;
}
50% {
bottom: 20px;
}
100% {
bottom: 0;
}
}
<button>Click Me!</button>
<button id="second-button">Now Click Me!</button>
You'll notice that if you press the button more than once the animation will not repeat. To work around this, use one of the techniques in this article:
var button = document.querySelector("button");
var secondButton = document.querySelector("#second-button")
button.onclick = function() {
secondButton.classList.remove("bounce");
secondButton.offsetWidth = secondButton .offsetWidth;
secondButton.classList.add("bounce");
}
I updated the code snippet.
Related
I am creating a game with HTML, CSS, & JavaScript. I have 5 h2(s) and I want to wait for the animation to finish before moving on to any part of the code. The animation works how I want it to but the JavaScript is starting the next animation before the first one is even done! I have tried using
window.setTimeOut
but no luck. Here is the code with the required code: https://codepen.io/HumanFriend/pen/mdOBvoL
Can someone help me?
You can listen to animationend event, fe:
const animated = document.querySelector('.animated');
animated.addEventListener('animationend', () => {
console.log('Animation ended');
});
Read more: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/animationend_event
Random thing:
When you use setTimeout(nextI_ifelse(), 5000); you just invoke the nextI_ifelse inline (and you're setting timeout for the value returned from this function). Change it to setTimeout(nextI_ifelse, 5000);
Any you just want to read about algorithms in general. What you try to do makes sense, but the way you're trying to achieve that does not. The for loop in your codepen runs instantly, so iLevel is directly set to the last value.
To elaborate on entio's answer, your animation occurs when an element has the class "typing-effect." When that animation ends, the browser calls an event called "animationend." You can use JavaScript to run your animation on the next element by accessing that event.
Notice in HTML the snippit below, I've moved the "display: hidden" to a CSS class and removed the "typing-effect." In my JavaScript function, I enable the class in the first element, increment the counter, and told the "animationend" to call the function again with the new value for "i."
Edit: I forgot to mention, I modified the id values. I don't believe a valid id value in HTML5 can contain parenthesis.
console.log("script.js connected");
let iLevel = 1;
let loop = 0;
function animateNext(i){
let stop = document.querySelectorAll('.animated').length;
let animated = document.querySelector(`#h2_${i}`);
animated.classList.add('typing-effect');
animated.addEventListener('animationend', () => {
if(i===stop){
iLevel = "iDone";
}else{
animateNext(i+1);
}
});
}
function startGame() {
animateNext(1);
}
.animated{
display: none;
}
.typing-effect {
display: block;
animation: typing-effect 5s steps(130, end), 0.75s step-end infinite;
white-space: nowrap;
overflow: hidden;
border-right: 2px solid black;
}
.typing-effect:after {
content: " ";
}
#keyframes typing-effect {
0% {
width: 0%;
}
100% {
width: 100%;
}
}
#keyframes blink-caret {
from,
to {
border-color: transparent;
}
50% {
border-color: black;
}
}
<button onclick="startGame();">START GAME</button>
<div id="instructions">
<div>
<h2 id="h2_1" class="animated">Welcome to The Number Wizrd</h2>
</div>
<div>
<h2 id="h2_2" class="animated">Adjfosdf</h2>
</div>
<div>
<h2 id="h2_3" class="animated">sosidjfs</h2>
</div>
<div>
<h2 id="h2_4" class="animated">difjspodf</h2>
</div>
<div>
<h2 id="h2_5" class="animated">skidjfosidf</h2>
</div>
</div>
I am currently learning on my own some CSS & JS and i'm stuck on a part i really want to work on but have trouble finding the right answers online as there seem to be a tons of methods yet i couldn't make any of them work.
Here is a snippet of what i have in mind :
let htmlcontent = `<p>It's me again!</p>`;
function animation() {
let content = document.getElementById("content");
content.innerHTML = "";
content.innerHTML = htmlcontent;
}
#content p {
font-size: 100px;
}
<div id="content">
<p>
Hello world!
</p>
</div>
<button onclick="animation()">
Click here
</button>
The idea is that when i click on the button, old content gets replaced by new HTML content and i want that new content to fade in from the right (a transition) every time i click the button.
I'm sorry if my question is bad/weird, english isn't my primary language and i have no one else to ask at the moment. Thank you for your patience.
You could just make a CSS animation and play that whenever you click the button.
let htmlcontent = `<p>It's me again!</p>`;
let content = document.getElementById("content");
function animation() {
content.innerHTML = htmlcontent;
content.classList.add("animate");
setTimeout(function() {
content.classList.remove("animate");
}, 500); // 500 is the same time as the CSS animation
}
#content p {
font-size: 100px;
}
.animate {
animation: fadeIn 500ms ease-out backwards;
}
#keyframes fadeIn {
from {
transform: translateX(250px);
opacity: 0;
}
to {
transform: translateX(0px);
opacity: 1;
}
}
<div id="content">
<p>
Hello world!
</p>
</div>
<button onclick="animation()">
Click here
</button>
To trigger a CSS transition, change the CSS state after you inserted the HTML. You can do this by changing a class (on the container or an inserted element).
Also see here:
Is it possible to animate a change to innerHTML using CSS only?
I've written a function that swaps a "Menu" button with a "Close" button when clicked (hiding one div and displaying another), and vice versa. I'm struggling to add an animation to the toggle of each swap.
This is what I have:
$(document).ready(function() {
$('#menu-button').on('click', function() {
$('#menu-button').toggleClass('inactive', 1000);
$('#close-button').toggleClass('inactive', 1000).toggleClass('active', 1000);
});
$('.close-trigger').on('click', function() {
$('#close-button').toggleClass('active').toggleClass('inactive', 1000);
$('#menu-button').toggleClass('inactive', 1000).toggleClass('active', 1000);
});
});
I've also tried fadeIn/fadeOut/fadeToggle instead of toggleClass to no avail. The problem with fadeToggle is that both elements briefly appear at the same time, and there's still no fade animation. Is there a better way to program this?
please try this
$(document).ready(function() {
$('#button1').on('click', function() {
$('#button1').hide();
$('#button2').show().addClass('toggle');
});
$('#button2').on('click', function() {
$('#button2').hide();
$('#button1').show().addClass('toggle');
});
});
#button2
{
display:none;
}
.button.toggle
{
opacity: 1;
animation-name: fadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 2s;
}
#keyframes fadeInOpacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<button id="button1" class="button" >button1</button>
<button id="button2" class="button" >button2</button>
If you wish to use toggleClass, you must accompany it with a CSS transition in your stylesheet. Otherwise, the element will simply disappear, as toggleClass does not provide animation by itself.
A CSS transition would be simple to add to your stylesheet, all that would be necessary would be to place these properties on the rule for your class:
transition-property: all;
transition-duration: 0.5s; /* or however long you need it to be */
Remember that properties such as display cannot be animated, so you must control the appearance using a property such as opacity, which can be animated because it is a number.
toggleClass() doesn't allow animation. The second argument is not the time. See the docs:
http://api.jquery.com/toggleclass/
I guess the best for you would be CSS transition:
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions
If you don't want to use transition, that would do the thing:
$('#menu-button').on('click', function() {
$('#menu-button').hide();
$('#close-button').fadeIn();
});
$('.close-trigger').on('click', function() {
$('#close-button').hide();
$('#menu-button').fadeIn();
});
(Please see this link to jsfiddle -
http://jsfiddle.net/AshThomas/742tvhqy/1/)
Hi there,
If this code runs on a computer... when the menu button is clicked, the button still appears 'hovered' until the cursor is moved (i.e. if you click the button and don't move the cursor, the button still appears 'hovered')
Also, if this code is run on the Samsung Galaxy S3 Mini's standard internet browser (this could be the same for other android phones), the menu opens and then closes instantly, even though the menu button is only pressed once.
I believe these two occurrences are linked but I cannot seem to find a solution.
Basically, I am looking to stop the menu button from appearing 'hovered' once the button is clicked (and without having to move the cursor) and I would like the menu to stay open when the menu button is pressed on the phone mentioned above... hopefully these two problems are related!
<body>
<div id="menu" class="panel" role="navigation" style="overflow-y: scroll; position: fixed;
top: 0px; bottom: 0px; width: 15.625em; height: 100%; -webkit-transition: right 300ms ease;
transition: right 300ms ease; right: -15.625em; -webkit-overflow-scrolling: touch;">
<div id="menuWrapper">
<ul>
<li class="boldMenu">Home
</li>
<li class="boldMenu">About
</li>
<li class="boldMenu">Contact
</li>
</ul>
</div>
</div>
<div class="wrap push" style="right: 0px; -webkit-transition: right 300ms ease; transition: right 300ms ease;">
☰
</div>
I've fixed your issue. I guess it's a bug of browser, because it's not re-rendering DOM elements after animation.
http://jsfiddle.net/742tvhqy/4/
Check out line #104
menuLink.on('click.bigSlide', function(e) {
e.preventDefault();
if (menu._state === 'closed') {
menu.open();
} else {
menu.close();
}
menuLink.fadeOut(5).fadeIn(10);
});
You see that last line with fadeOut/fadeIn? That's the fix. I've tried with hide().show(); but it's not working, even if i use fadeOut(1) it's not working :) But common, 5ms is same as 1ms. I can't think any better solution right now. It works.
BTW. In your place I would just do all this stuff with few lines of jQuery code instead of all that fancy css animation stuff..
maybe do this... add another class to the button and give the class the hovered properties in css...
menu-link-class:hover {...}
then do this in your js
$('.menu-link').click(function() {
var me = $(this);
me.removeClass('menu-link-class');
setTimeout(function() {
me.addClass('menu-link-class');
},1);
});
UPDATE:
Special thanks to #Lukas Liesis
you have 2 choises :)
menuLink.on('click.bigSlide', function(e) {
e.preventDefault();
if (menu._state === 'closed') {
menu.open();
} else {
menu.close();
}
menuLink.fadeOut(5).fadeIn(10);
});
or
menuLink.on('click.bigSlide', function(e) {
e.preventDefault();
if (menu._state === 'closed') {
menu.open();
} else {
menu.close();
}
menuLink.removeClass('menu-link-class');
setTimeout(function() {
menuLink.addClass('menu-link-class');
},1);
});
I'm trying to slide a div from the left to the right side when the 'submit' button is clicked. After a little pause, the div would automatically slides back to it's original position. Currently it goes to the right side but it isn't coming back to the left corner.
CSS
#mainform{
position: absolute;
display: block;
padding-top:20px;
font-family: 'Fauna One', serif;
}
HTML
<div id="mainform">
<!-- Required div starts here -->
<form id="form">
<h3>Contact Form</h3>
<div class="hello"></div>
<input type="button" id="submit" value="Send Message"/>
</form>
</div>
JS
$(document).ready(function() {
$('#submit').click(function(e) {
reslide();
function reslide() {
$('#mainform').delay().animate({width: '510px', left: '1050'}, 600).delay(5000).animate({width: '510px', right: '1000px'}, 200, function() {
setTimeout(reslide, 3000);
});
}
$('.hello').fadeIn(1500);
$("<b>Successfully send</b>").appendTo(".hello");
$('.hello').fadeOut(2500);
});
});
When you give feedback to the user after/before submiting, try to use CSS3 Transform instead of actually moving/resizing the object.
function slide($obj) { // jQuery object of element
$obj.css("transform", "translateX (50px)");
setTimeout(function(){
$obj.css("transform", "none");
}, 5000);
}
To make it smooth (real animation) apply CSS3 Transition property.
<style>
.object {
transition: transform 0.6s;
}
</style>
Or you can shorten, if you're sure everything'd go smoothly.
function slide($obj) { // jQuery object of element
$obj.animate("transform", "translateX (50px)")
.delay(600).
.animate("transform", "translateX (0px)");
}
PS; in my expirience jQuery.delay(); wasn't always working with queueing animations, i'm not entirely sure why. As a matter of fact, this happened only sometimes. Sometimes tought it wasn't working
// not working
$("smth").animate({"rule":"val"}).delay(500).animate("rule":"val");
// working
$("smth").animate({"rule":"val"})
setTimeout(function(){
$("smth").animate({"rule":"val"})
}, 1000);
The reason it's not working is that, while you add right to the element, you also keep left with its original value, thus the element will not "come back". Add left: '', to the 2nd animate function and you should be good to go:
function reslide() {
$('#mainform').delay().animate({
width: '510px',
left: '1050'
}, 600).delay(5000).animate({
width: '510px',
left: '',
right: '1000px'
}, 200, function () {
setTimeout(reslide, 3000);
});
}
Here is a fiddle you can play with: http://jsfiddle.net/bv8dwaq2/