Reputation: 120
I want to have many div elements and each element will have its own "button" element inside it. When the button is clicked, the div containing it should slowly fade out.
I first tested out the idea by passing the parent of the "button" element (which will be the div element) inside "onclick" event. The function called stored the opacity inside a variable and decreased it by 0.1 if the opacity was greater than 0. This effect could be seen every time the "button" inside div was clicked until it became zero and the <div>
disappeared.
I want to achieve this automatically over a period of time that looks like an animation, so I thought of using the setTimeout or setInterval functions inside the main function that was called. But, the code executes instantaneously as if the javascript just ignored the timers. I have included a console.log to print the value of opacities. I could see them compute to 0 instantaneously.(setInterval also fails for me) Its the same as if I was setting the "display" property to "none" inside the function.
var btn = document.getElementById("start");
var timerID = 0;
function hide(elem) {
var opacity =
Number(window.getComputedStyle(elem).getPropertyValue("opacity"));
if (opacity > 0) {
opacity = opacity - 0.1;
console.log(opacity);
elem.style.opacity = opacity;
/* you can simply comment out the setTimeout function and see that the
opacity reduces on every click of the <button> */
setTimeout(hide(elem), 2000);
} else {
clearTimeout(timerID);
}
}
.box {
height: 250px;
width: 250px;
background: red;
}
<div class="box">
<button id="start" onclick="hide(this.parentNode)">CLICK
ME</button>
</div>
Upvotes: 1
Views: 2349
Reputation: 170
if you do not want the solutions with css, keeping your code is possible, but has a bit of lag.
var btn = document.getElementById("start");
var timerID = null;
function hide(elem) {
timerID = setInterval(() => {
var opacity = Number(window.getComputedStyle(elem).getPropertyValue("opacity"));
if (opacity > 0) {
opacity = opacity - 0.1;
console.log(opacity);
elem.style.opacity = opacity;
} else {
clearInterval(timerID);
}
}, 200);
}
Upvotes: 0
Reputation: 60
First you want setInterval because setTimeout is meant to run once while the interval is meant to continuously run. Second, you are clearing your timerID that you created and never used anywhere else. So you're stopping nothing. Start the interval, clear the interval when everything is the way you want it to end. The below example is what I think you're looking for.
<!DOCTYPE html>
<html>
<style>
.box {
height: 250px;
width: 250px;
background: red;
}
</style>
<body>
<div class="box">
<button id="start" onClick="hide(this.parentNode)">CLICK ME</button>
</div>
<script>
function hide(elem) {
var opacity = Number(window.getComputedStyle(elem).getPropertyValue("opacity"));
var opacityChange = setInterval(change, 20);
function change() {
if (opacity > 0) {
opacity -= 0.1;
elem.style.opacity = opacity;
} else {
clearInterval(opacityChange);
}
}
}
</script>
</body>
</html>
Upvotes: 0
Reputation: 136124
You can just usee css transitions.
function hide(elem) {
elem.classList.add("fade-out")
}
.box {
height: 250px;
width: 250px;
background: red;
}
.fade-out {
-webkit-transition: opacity 3s ease-in-out;
-moz-transition: opacity 3s ease-in-out;
-ms-transition: opacity 3s ease-in-out;
-o-transition: opacity 3s ease-in-out;
opacity: 0;
}
<div class="box">
<button id="start" onclick="hide(this.parentNode)">CLICK
ME</button>
</div>
Upvotes: 3
Reputation: 207919
You're calling your function immediately with setTimeout(hide(elem), 2000);
and need to wrap it within a function like setTimeout(function(){hide(elem)}, 2000);
var btn = document.getElementById("start");
var timerID = 0;
function hide(elem) {
var opacity =
Number(window.getComputedStyle(elem).getPropertyValue("opacity"));
if (opacity > 0) {
opacity = opacity - 0.1;
console.log(opacity);
elem.style.opacity = opacity;
/* you can simply comment out the setTimeout function and see that the
opacity reduces on every click of the <button> */
setTimeout(function(){hide(elem)}, 2000);
} else {
clearTimeout(timerID);
}
}
.box {
height: 250px;
width: 250px;
background: red;
}
<div class="box">
<button id="start" onclick="hide(this.parentNode)">CLICK
ME</button>
</div>
Upvotes: 1