I'm trying to show an element for a short amount of time, then hiding it with a CSS transition, on a button click.
Here's the outline of what I did.
elem has a property of opacity: 0.
Fire event when button gets selected.
The events function will add, then remove a class named show to elem.
CSS has the following property: transition: opacity 500ms ease 1000ms;.
#elem.show has a property of opacity: 1.
The problem is, nothing happens when the button gets clicked on. How can I make element get shown, without a transition effect, then, after 1s close with a transition?
JSFiddle
var btn = document.getElementById('btn');
var elem = document.getElementById('elem');
btn.addEventListener('click', function() {
elem.classList.add('show');
elem.classList.remove('show');
});
#elem {
background-color: orange;
width: 100px;
height: 100px;
opacity: 0;
transition: opacity 500ms ease 1000ms;
}
#elem.show {
opacity: 1;
transition: none;
}
<button id="btn">Press Me</button>
<div id="elem"></div>
Using setTimeout is not tidy - it is better to listen to the animation end event and remove the show class. I have also used animation to show and hide the element successively - see demo below:
var btn = document.getElementById('btn');
var elem = document.getElementById('elem');
btn.addEventListener('click', function() {
elem.classList.remove('show');
// this force-restarts the CSS animation
void elem.offsetWidth;
elem.classList.add('show');
});
elem.addEventListener("animationend", function(){
elem.classList.remove('show');
}, false);
#elem {
background-color: orange;
width: 100px;
height: 100px;
opacity: 0;
}
#elem.show {
animation: anime 1s 1;
}
#keyframes anime {
0% {
opacity: 1;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
<button id="btn">Press Me</button>
<div id="elem"></div>
Update
Listening to the animation-end event do not seem necessary actually - it works properly even without it. The gist here is the use of void elem.offsetWidth to forcefully restart the animation:
var btn = document.getElementById('btn');
var elem = document.getElementById('elem');
btn.addEventListener('click', function() {
elem.classList.remove('show');
// this force-restarts the CSS animation
void elem.offsetWidth;
elem.classList.add('show');
});
#elem {
background-color: orange;
width: 100px;
height: 100px;
opacity: 0;
}
#elem.show {
animation: anime 1s 1;
}
#keyframes anime {
0% {
opacity: 1;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
<button id="btn">Press Me</button>
<div id="elem"></div>
just do this :
setTimeout(function() { elem.classList.remove('show'); }, 1000);
instead of writing :
elem.classList.remove('show');
To handle repeated clicks, do this ::
var btn = document.getElementById('btn');
var elem = document.getElementById('elem');
var timeOutFunc;
btn.addEventListener('click', function() {
elem.classList.add('show');
clearTimeout(timeOutFunc);
timeOutFunc = setTimeout(function() {elem.classList.remove('show') } , 1000);
});
This borrows from other answers, and addresses the multiple press "issue"
var btn = document.getElementById('btn');
var elem = document.getElementById('elem');
btn.addEventListener('click', (function() {
var timer = null;
return function() {
elem.classList.add('show');
if (timer) {
clearTimeout(timer);
timer = null;
}
timer = setTimeout(e => elem.classList.remove('show'), 1000);
};
})());
#elem {
background-color: orange;
width: 100px;
height: 100px;
opacity: 0;
transition: opacity 500ms ease 500ms;
}
#elem.show {
opacity: 1;
transition: none;
}
<button id="btn">Press Me</button>
<div id="elem"></div>
Try with this...i Hope its resolved your prblm
https://jsfiddle.net/b3en368p/5/
var btn = document.getElementById('btn');
var elem = document.getElementById('elem');
btn.addEventListener('click', function() {
elem.classList.add('show');
setTimeout(function(text){
elem.classList.remove('show');
}, 1000);
});
Add css
#elem {
background-color: orange;
width: 100px;
height: 100px;
display: none;
}
#elem.show {
display: block;
}
Your listener should be like this-
btn.addEventListener('click', function() {
elem.classList.add('show');
setTimeout(function(){
elem.classList.remove('show');
}, 1000);
});
Related
My animation function only runs once. I've tried removing and adding classes, as well as running a animationend function to create a retrigger. But still no luck. Any vanilla JS ideas?
CSS:
#element {
width: 10px;
height: 10px;
animation: "";
#keyframes movedown {
100% {
transform: translateY(10px);
}
}
JS:
btn_button.onclick = () => {
element.style.animation = "movedown 10s";
};
HTML:
<div id="element"></div>
You can use setTimeout to set element.style.animation to "". Then, you can add animation name again upon button click.
let btn = document.querySelector("#btn");
btn.onclick = () => {
element.style.animation = "movedown 2s";
setTimeout(() => element.style.animation = "", 2000)
};
#element {
width: 10px;
height: 10px;
background-color: red;
}
#keyframes movedown {
100% {
transform: translateY(50px);
}
}
<div id="element"></div>
<button id="btn">Trigger</button>
I created a page where the background colors of a div change every so often. I want to make it so that when the mouse is over(or hovers) the color changer pauses where it is, as long as the mouse hovers there. And when the mouse no longer hovers the div, the colors continue to change where it left off. The closest examples I ran into on this website used JQuery solutions. I am not looking for a JQuery solution. I am looking for a javascript solution. I appreciate any and all of your responses. Thank You!
var dammit = document.getElementById("muck");
var colorChange = document.getElementById("color-changer");
var colors = ["red", "blue", "green", "pink"];
var counter = 0;
function changer() {
if (counter >= colors.length) {
counter = 0;
};
colorChange.style.background = colors[counter];
counter++;
};
var myTimer = setInterval(changer, 3000);
body {
background: #FDCA40;
margin: 0;
padding: 0;
-webkit-transition: background 0.9s;
-moz-transition: background 0.9s;
transition: background 0.9s;
}
div#muck {
width: 100%;
height: 100vh;
}
<body id="color-changer">
<div id="muck"></div>
</body>
There is no way to pause a timer, but you can just stop the currently running one and then start a new one.
(FYI: All browsers that are within 5 years old at least support CSS transitions. No need to vendor prefix that.)
var source = document.getElementById("muck");
var colorChange = document.getElementById("color-changer");
var colors = ["red", "blue", "green", "pink"];
var counter = 0;
function changer(){
if (counter >= colors.length){
counter = 0;
};
colorChange.style.background = colors[counter];
counter++;
};
var myTimer = setInterval(changer, 1000);
// Stop the current timer when mouseover
source.addEventListener("mouseover", function(){ clearInterval(myTimer)});
// Start a new timer when mouse out
source.addEventListener("mouseout", function(){ myTimer = setInterval(changer, 1000);});
body{
background: #FDCA40;
margin: 0;
padding: 0;
transition: background 0.9s;
}
div#muck{
width: 100%;
height: 100vh;
}
<body id="color-changer">
<div id="muck"></div>
</body>
You can do this purely in CSS but you need to use animation. I also added some CSS variables so the animation is easier to change.
body {
background: #FDCA40;
margin: 0;
padding: 0;
}
/* Safari 4.0 - 8.0 */
#-webkit-keyframes example {
from {background-color: red;}
to {background-color: yellow;}
}
#keyframes example {
0% {background-color: red;}
20% {background-color: blue;}
40% {background-color: green;}
80% {background-color: pink;}
100% {background-color: red;}
}
div#muck {
--animation-transition-speed: 0.9s;
--number-of-colors: 4;
width: 100%;
height: 100vh;
-webkit-animation-name: example;
-webkit-animation-duration: calc(var(--animation-transition-speed) * var(--number-of-colors));
animation-name: example;
animation-duration: calc(var(--animation-transition-speed) * var(--number-of-colors));
animation-iteration-count: infinite;
}
div#muck:hover {
animation-play-state: paused;
}
<body id="color-changer">
<div id="muck"></div>
</body>
While this doesnt really pouse the interval it mimics what you need very closely..
You can use a flag.. something like this:
var output = document.getElementById('id')
var isPaused = false;
var counter = 0;
window.setInterval(function() {
if(!isPaused) {
counter++;
if (counter >= colors.length) {
counter = 0;
};
colorChange.style.background = colors[counter];
}
}, 1000);
document.getElementById('muck').addEventListener('mouseenter', function(e) {
isPaused = true;
});
document.getElementById('muck').addEvenetListener('mouseleave', function(e) {
isPaused = false;
});
from Javascript - Pausing setInterval()
Counter doesn't work properly . I would like to get result when counterFun function toggle .active class and show number in every 1s. For now class is toggled but shows every 2nd number and it doesn't looks like it happen every 1sek
let clickNumber = 0;
const time = 1000;
const h1 = document.querySelector('h1');
function counterFun() {
clickNumber++;
h1.textContent = clickNumber;
h1.classList.toggle('active');
console.log(clickNumber);
}
setInterval(counterFun, time);
.regular {
opacity: 0;
}
.active {
font-size: 100px;
opacity: 1;
transition: .4s;
}
HTML
<div>
<h1 class="regular active">0</h1>
</div>
Your problem is you are using .toggle which doesn't toggle again until the second iteration. So basically you end up with:
0 - toggle
1 - off
2 - toggle
3 - off
Your options are to either use .remove and .add for the class or add a second .toggle.
Example with remove:
let clickNumber = 0;
const time = 1000;
const h1 = document.querySelector('h1');
function counterFun() {
h1.classList.remove('active');
clickNumber++;
h1.textContent = clickNumber;
h1.classList.add('active');
console.log(clickNumber);
}
setInterval(counterFun, time);
.regular {
opacity: 0;
}
.active {
font-size: 100px;
opacity: 1;
transition: .4s;
}
HTML
<div>
<h1 class="regular active">0</h1>
</div>
Example with Toggle:
let clickNumber = 0;
const time = 1000;
const h1 = document.querySelector('h1');
function counterFun() {
h1.classList.toggle('active');
clickNumber++;
h1.textContent = clickNumber;
h1.classList.toggle('active');
console.log(clickNumber);
}
setInterval(counterFun, time);
.regular {
opacity: 0;
}
.active {
font-size: 100px;
opacity: 1;
transition: .4s;
}
HTML
<div>
<h1 class="regular active">0</h1>
</div>
Because you need to remove and add the class at the same time, you can use this code
let clickNumber = 0;
const time = 1000;
const h1 = document.querySelector('h1');
function counterFun() {
$("#demo").addClass("active").delay(800).queue(function(next){
$(this).removeClass("active");
clickNumber++;
h1.textContent = clickNumber;
next();
});
console.log(clickNumber);
}
setInterval(counterFun, time);
.regular {
opacity: 0;
}
.active {
font-size: 100px;
opacity: 1;
transition-delay: .4s;
transition: .4s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<h1 class="regular active" id="demo">0</h1>
</div>
PS: you need jquery
I am trying animating an element which has display property set to null. Objective is to recreate something that bootstrap does in modal.
Further Explanation:
An element which is set to display none on page load but when a user clicks a certain button it shows up with animation (fade in for example). Then when user click on close button or that button again it fades out and its display property is set to none again.
Problem:
When box display property is set to none. And i click on the button. It's display is set to block and adding class "Show" both occur simultaneously and instantaneously so element just shows rather than animating
Here is my Code:
HTML:
<button id="btn">Show / Hide</button>
<div id="box" class="show">
</div>
CSS:
#box {
background-color: aquamarine;
height: 100px;
width: 100px;
opacity: 0;
transition: ease all 0.3s;
}
#box.show {
transition: ease all 0.3s;
opacity: 1;
}
Javascript:
var box = document.querySelector("#box");
var btn = document.querySelector("#btn");
box.style.display = "none"
btn.addEventListener("click", function () {
if(box.style.display == "none") {
return new Promise(function(resolve, reject) {
box.style.display = "block";
resolve();
}).then(function() {
box.classList.add('show');
});
} else if(box.style.display == "block") {
return new Promise(function(resolve, reject) {
box.addEventListener('transitionend', function () {
box.style.display = "none";
})
resolve();
}).then(function() {
box.classList.remove('show');
});
}
});
JSFiddle: https://jsfiddle.net/ptLggbmb/1/
Instead of using Promises you could simply use the transitionend listener and for the fadeIn animation force a layout/reflow before applying the class to the box.
var box = document.querySelector("#box");
var btn = document.querySelector("#btn");
btn.addEventListener("click", function() {
var prevDisplay = box.style.display;
var listener = function() {
box.style.display = "none";
removeListener(listener);
};
if (prevDisplay !== "none") {
addListener(listener);
box.classList.remove('show');
} else {
removeListener(listener);
box.style.display = null;
box.offsetLeft;
box.classList.add('show');
}
function addListener(fn) {
box.addEventListener('transitionend', fn);
}
function removeListener(fn) {
box.removeEventListener('transitionend', fn);
}
});
#box {
background-color: aquamarine;
height: 100px;
width: 100px;
opacity: 0;
transition: ease all 0.3s;
}
#box.show {
transition: ease all 0.3s;
opacity: 1;
}
<button id="btn">Show / Hide</button>
<div id="box" class="show">
</div>
I think you overcomplicated this to the extreme, IMHO. Try this (Pure CSS with a simple JS toggle of classes):
https://jsfiddle.net/ptLggbmb/17/
HTML:
<button id="btn">Show / Hide</button>
<div id="box" class="show">
CSS:
#box {
background-color: aquamarine;
height: 100px;
width: 100px;
opacity: 0;
display: none;
transition: ease all 1s;
}
#box.show {
display: block;
opacity: 1;
}
JS:
var box = document.querySelector("#box");
var btn = document.querySelector("#btn");
btn.addEventListener("click", function () {
box.classList.toggle('show');
});
With the following line of code:
document.getElementById("myDiv").innerHTML=txt;
Is it possible to add the .fadeIn("slow" ) function? I would like the new text to fade in.
Do it with js+CSS.
With a CSS transition it will fade in.
You need to have the font-color set to background-color.
First change content,
then change color to normal font color.
Your js:
document.getElementById("myDiv").innerHTML=txt;
document.getElementById("myDiv").style.color = "#333333";
Your CSS:
#myDiv {
color: #ffffff;
transition: color 2s ease 0s;
}
Ended up just doing this:
$("div.col-lg-6").replaceWith(function() {
return $(txt).hide().fadeIn(1000);});
A bit of a hack, but you could do it like this: http://codepen.io/zvona/pen/LVxxjM
Where we use CSS transitions for the purpose.
<button class='add'>Add text</button>
<button class='clear'>Clear text</button>
<div id="myDiv"></div>
and:
#myDiv {
opacity: 0;
transition: opacity 1000ms;
}
#myDiv.show {
opacity: 1;
}
and:
var myDiv = document.querySelector("#myDiv");
document.querySelector(".add").addEventListener('click', function() {
myDiv.textContent = "Fade magic";
myDiv.classList.add('show');
}, false);
document.querySelector(".clear").addEventListener('click', function() {
myDiv.classList.remove('show');
}, false);
In CSS
#mydiv {
opacity: 0;
transition: opacity 2s;
}
In JS
document.getElementById("myDiv").style.opacity= "1";
Try not to worry about fading in/out the innerHTML property. Instead, wrap the innerHTML in a span tag (or, alternatively, a div tag), and then simply fade that element in and out.
Here it is with a 1,000 millisecond delay:
const fadetime = 1000;
function fadeInElement(element) {
element.style.removeProperty('display');
setTimeout(function() {
element.classList.remove('fade');
}, 10);
return true;
}
function fadeOutElement(element) {
element.classList.add('fade');
setTimeout(function() {
element.style.display = 'none';
}, fadetime);
return true;
}
var buttondisplay = false;
document.getElementById('button').addEventListener('click', function(ev) {
if(buttondisplay) {
fadeOutElement(document.getElementById('button-text-2'));
setTimeout(function() {
fadeInElement(document.getElementById('button-text-1'));
}, fadetime);
} else {
fadeOutElement(document.getElementById('button-text-1'));
setTimeout(function() {
fadeInElement(document.getElementById('button-text-2'));
}, fadetime);
}
buttondisplay = !buttondisplay;
});
.fadeable {
opacity: 1;
transition: opacity 1s;
}
.fade {
opacity: 0 !important;
}
<button id="button">
<span id="button-text-1" class="fadeable">First Text</span>
<span id="button-text-2" class="fadeable fade" style="display:none;">Second text!</span>
</button>