I'm trying to get a CSS3 animation to animate every time a function is called.
My CSS code for the animation is in a class called 'enable' and it simply starts the animation.
My FUNCTIONS code is as follows:
document.getElementById("red").className = "enable";
setTimeout(function() {
document.getElementById("red").className = "";
}, 1000);
That works properly when using the setTimeout function but when i change the entire FUNCTIONS code to say like this:
document.getElementById("red").className = "";
document.getElementById("red").className = "enable";
It only works once.
Why can't I remove the class and then add it immediately after.
Why doesn't my second code do the same thing as the first one?
Thanks in advanced!
It may be helpful if included your html/css.
You have to use the setTimeout, otherwise the browser is not quick enough to pick up the change. Since javascript runs in a single thread, there is some breathing time needed for the browser to react to the change in class.
Here is an example: http://jsfiddle.net/brendonparker/75TfR
<!-- CSS -->
<style>
#mydiv {
-webkit-transition: all ease 1s;
transition: all ease 1s;
}
#mydiv.enabled {
background: red;
}
</style>
<!-- HTML -->
<div id="mydiv" >
<p>Hello World</p>
<p>Test</p>
</div>
<!-- JS -->
<script>
function animate(){
var d = document.getElementById('mydiv');
d.className = 'enabled';
setTimeout(function(){
d.className = '';
}, 1000);
}
animate();
</script>
Related
How would I set display to none (and vice versa) only after the CSS transition has finished?
This is my current code but it doesn't work nicely – the transition isn't visible because I'm adding/removing display:none; straightaway.
<script type="text/javascript">
var mobile_menu = document.querySelector('#mobile-menu');
var mobile_menu_open = document.querySelector('#open-mobile-menu');
var mobile_menu_close = document.querySelector('#close-mobile-menu');
mobile_menu_open.addEventListener('click', function (event) {
mobile_menu.classList.remove('duration-100', 'ease-in', 'opacity-0', 'scale-95');
mobile_menu.classList.add('duration-200', 'ease-out', 'opacity-100', 'scale-100');
mobile_menu.removeAttribute('style');
});
mobile_menu_close.addEventListener('click', function (event) {
mobile_menu.classList.remove('duration-200', 'ease-out', 'opacity-100', 'scale-100');
mobile_menu.classList.add('duration-100', 'ease-in', 'opacity-0', 'scale-95');
mobile_menu.style.display = "none";
});
</script>
I can only think of setTimeout(); but in most cases it's not considered a proper solution but rather a dirty hack. Do I have any other options here?
You can use the transitionend event listener.
mobileMenu.addEventListener('transitionend', setDisplayNone);
After the animation is finished, it will execute setDisplayNone(). If you only want to run this once, you can add this at the end of the setDisplayNone function:
mobileMenu.removeEventListener('transitionend', setDisplayNone);
Example:
var div = document.querySelector('div')
function setDisplayNone() {
div.style.display = 'none'
}
document.querySelector('button').onclick = function() {
div.addEventListener('transitionend', setDisplayNone);
div.classList.add('transition')
}
.transition {
transition-duration: 3s;
opacity: 0;
}
<button>Click me!</button>
<br>
<div id='someDiv'>
Click the button!
</div>
This text will shift upwards once the div has display:none
http://jsfiddle.net/pdb4kb1a/2/
The code works just fine on JSFiddle, but I cant get it to work when I use it in a HTML/CSS file. Only the 50x200 image is displayed, no signs of the simple slideshow or fade effect. I work in Sublime text, could that create any problems?
var imgArray = [
'http://placehold.it/300x200',
'http://placehold.it/200x100',
'http://placehold.it/400x300'],
curIndex = 0;
imgDuration = 3000;
function slideShow() {
document.getElementById('slider').className += "fadeOut";
setTimeout(function() {
document.getElementById('slider').src = imgArray[curIndex];
document.getElementById('slider').className = "";
},1000);
curIndex++;
if (curIndex == imgArray.length) { curIndex = 0; }
setTimeout(slideShow, imgDuration);
}
slideShow();
#slider {
opacity:1;
transition: opacity 1s;
}
#slider.fadeOut {
opacity:0;
}
<body>
<img id="slider" src="http://placehold.it/50x200">
</body>
JSFiddle executes the javascript code in the window.onload event. You can change this if you click the JavaScript Button in the editor of JSFiddle.
If you change it to No wrap - in <head> you'll see that it doesn't work as well. You should see an error in your console, telling you the reason.
I'm assuming that you're including your script snippet in the head section of your HTML Document.
If you take your code as posted in your question, your slider isn't loaded yet, because the script is executed before your HTML document is fully loaded. You have to wrap the call to your slideShow function inside the onloadevent (or if you're using jQuery you'll probably use $(document).ready(function(){ ... }) instead.
This should do the trick then:
window.onload = function() {
slideShow();
}
Including the script at the bottom of your HTML document should work as well as an alternative.
How can I add transition to document.getElementById("myDIV").style.display = "none"; I am currently working on a registration form in which if one input is of a certain value the other div is hidden but it looks so rough, Is there a way to add transitions into the following JS ?
<script type="text/javascript">
function myFunction() {
document.getElementById("myDIV").style.display = "none";
}
function hideshow(which){
if (!document.getElementById)
return
if (which.style.display=="block")
which.style.display="block"
else
which.style.display="block"
}
function myFunction1() {
document.getElementById("myDIV2").style.display = "none";
}
</script>
Create functions with parameters like
function hideDiv(div_id) {
document.getElementById(div_id).style.display = "none";
}
function showDiv(div_id) {
document.getElementById(div_id).style.display = "block";
}
The way to make a nice transition is to set style.display= "none" after you perform some kind of animation that removes the element from view.
You could:
Fade it out (set opacity to 0 - fade it with transition in CSS)
Slide it up/down/left/right (animation library or fancy CSS)
Do some other fancier animation (like bounce, shrink etc.)
Then, set style.display = "none"
The easiest way to do this (in my opinion) is with an animation library. I personally recommend VelocityJS because you don't need jQuery to run it.
I don't think there is anyway to do that with simple js, however I did it easily using JQuery
<script type="text/javascript">
$(document).ready(function(){
$("#myDIV").show();
$(document).on('click', '.married' , function() {
if (this.value == "never_married"){
$("#myDIV").hide('slow');
} else {
$("#myDIV").show('slow');
}
})
});
The reason is display isn't animated, setting it from block to none won't give you the result you're looking for.
A nice way to do this is to use CSS alongside JavaScript for the transition.
Add Transition to your myDIV style such as:
#myDIV {
opacity: 1;
transition: 1s ease;
}
#myDIV.hidden {
opacity: 0;
transition: 1s ease;
}
Then with JavaScript apply the hidden class to #myDiv and you'll get your animation.
Once the animation has finished then set el.style.display = 'none'; to make it disappear completely from view.
I have a block which content is being dynamically changed by script and I want that content not to change instantly, but fade out and then fade in with new content.
I want that done without jQuery — pure JS and CSS.
I am trying to do this in such a way:
I've defined transparent and opacle classes in CSS with transition set to 2s, and wanna toggle that classes for block with content when the content changes. As I expect it should smoothly fade out old content and fade in new content. But in fact content just changes instantly.
CSS:
.non-opacle {
opacity:0;
transition: opacity 2s linear;
}
.opacle {
opacity:1;
transition: opacity 2s linear;
}
HTML
<div class="alert alert-info" id="wrapper">
<p id="text-box">…</p>
</div>
JS
var textBox = document.getElementById('text-box');
window.onload = function () {
var failCounter = 0;
var current = notes[Math.floor(Math.random() * 12)];
textBox.className = 'opacle';
textBox.innerHTML = '…';
function keyClicked(event) {
if (event.target.className.split(' ')[1] === current) {
textBox.className = 'non-opacle';
textBox.innerHTML = '*some altered content*';
textBox.className = 'opacle';
…
In JS I initially set content wrapper block to 'opacle' class with initial content, and then on certain conditions, I set it to 'non-opacle', change block's innerHTML to place relevant content, and set the class back to 'opacle'.
But no animation occurs( What am I doing wrong?
Your problem is that you're adding and removing the opacity at the same time, before the initial transition has had time to complete.
What you need to do is delay the changing of the innerHTML and resetting of the opacity until the transition has completed.
Here's a very simple looping example to illustrate the principle, the important part to note is the setTimeout.
var p=document.getElementById("change"),text=["One","Two","Three","Four","Five"],x=0,interval=setInterval(function(){
x++;if(x===text.length)x=0;
p.classList.add("hide");
setTimeout(function(){
p.innerHTML=text[x];
p.classList.remove("hide");
},500);
},2000);
#change{
color:#000;
font-family:arial;
padding:5px;
transition:opacity .5s linear;
}
.hide{
opacity:0;
}
<p id="change">One</p>
The browser is not going to wait for transitions to complete before setting the class back to opacle.
This simple working fiddle moves the transition out to a separate selector, and uses a transitionend event listener, to wait for the element to be completely faded out before changing the content and fading it back in.
http://jsfiddle.net/0m3Lpwxo/1/
CSS:
.opacle {
opacity:1;
}
.non-opacle {
opacity:0;
}
#test {
transition: opacity 1s linear;
}
html:
<div id="test" class="non-opacle">this is content</div>
<button onclick="toggle()">toggle</button>
js:
function transitionEnded() {
var el = document.getElementById('test');
el.innerHTML = "hello.";
el.classList.remove('non-opacle');
}
function toggle() {
var el = document.getElementById('test');
el.addEventListener("transitionend", transitionEnded, true);
el.classList.add('non-opacle');
}
You probably just need to define browser specific styles along side your current definition (for example: -webkit-transition: opacity 2s linear;)
Also, I would say that instead of adding the transition redundantly to both classes, target something about your element that's not going to change, like its ID and define the transition style rules there. That way you will keep your CSS more DRY.
Here's the best reference material for dealing with CSS transitions: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_transitions
Try this:
<div id="myElement">Text</div>
function fadeOut(id,val){
if(isNaN(val)){ val = 9;}
document.getElementById(id).style.opacity='0.'+val;
//For IE
document.getElementById(id).style.filter='alpha(opacity='+val+'0)';
if(val>0){
val--;
setTimeout('fadeOut("'+id+'",'+val+')',90);
}else{return;}
}
function fadeIn(id,val){
if(isNaN(val)){ val = 0;}
document.getElementById(id).style.opacity='0.'+val;
//For IE
document.getElementById(id).style.filter='alpha(opacity='+val+'0)';
if(val<9){
val++;
setTimeout('fadeIn("'+id+'",'+val+')',90);
}else{return;}
}
Referred from this.
I have used following JS:
function change(){
var d = document.getElementById("div");
d.className = d.className + " non-opacle";
setTimeout(function(){
d.className = "opacle";
d.innerHTML = "TEST";
},1000);
}
See following DEMO, with CSS:
.opacle {
opacity:1;
transition: opacity 1s linear;
}
.non-opacle {
opacity:0;/* No need to add transaction here */
}
this code fades in and fades out the div #shape while the start variable is true.
when i call the "start" method from event "click" the browser stops working because the while inside method is infinitive and "click" event does not finish until "start" method is done.
i want the method to run after the "click" event is finished.
what should i do?
CSS
#shape {
background-color:red;
width:100px;
height:100px;
display:none;
}
HTML
<div id="shape"></div>
<button id="startButton">start game!</button>
JS
var start = false;
$("#startButon").click(function () {
start = true;
startGame();
});
function startGame() {
while (start == true) {
$("#shape").fadeIn(1000).delay(1000).fadeOut(1000);
}
}
You don't need the flag, just make a recursive function. I changed the time to 300 milliseconds so you can see it easier
http://jsfiddle.net/zfbptz9c/
$("#startButton").click(function () {
startGame();
});
function startGame() {
$("#shape").fadeIn(300, function () {
$("#shape").fadeOut(300, function () {
startGame();
});
});
}
The div will fade in and on complete of the fade in, it will fade out then call the startGame function again and the entire process will repeat infinitely.
Alternatively, this can be achieved with css only if you only need to target modern browsers. I will put this fiddle link here, it is from a different question. I won't paste the code since you did not tag the question with css but the fiddle shows everything. I take no credit for it.
How can I create a looping fade-in/out image effect using CSS 3 transitions?
http://jsfiddle.net/FTLJA/261/
JavaScript runs in a single threaded environment, meaning once you enter an infinite loop, you can only quit the loop from within it. In synchronous execution, like the one you have here, no code outside the loop can affect the loop condition.
As far as your problem, people suggested solutions such as making a recursive function or using CSS3 transitions.
Another possible way could be to use timing functions like setTimeout and/or setInterval
The code bellow will make the fadeIn/Out happen after every second, after start button is clicked and until stop button is clicked.
var toggle = true; // flag for animation direction
var shape = $("#shape"); // so we don't select the shape each time we animate
var duration = 1000; // animation duration
var delay = 1000; // delay between animations
var timerId; // timer id returned by setInterval
// start animating the shape after the delay
$("#startButton").click(function() {
timerId = setInterval(animate, delay);
});
// stop animating the shape and hide it
$("#stopButton").click(function() {
clearInterval(timerId);
shape.css('display', 'none');
});
// function that animates the shape depending on the toggle flag
function animate() {
if (toggle) {
shape.fadeIn(duration);
toggle = false;
} else {
shape.fadeOut(duration);
toggle = true;
}
}
#shape {
background-color: red;
width: 100px;
height: 100px;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="shape"></div>
<button id="startButton">start game!</button>
<button id="stopButton">stop game!</button>