Javascript function to FadeIn and FadeOut html item - working solution - javascript

HTML
<div id="notifyProductName">
Angualar JS
<a href="" ng-click="cart.addItem(product.name,product.price, 1);cart.ShowItem(product.name)">
JavaScript
cart.prototype.ShowItem = function (productName)
{
document.getElementById("notifyProductName").innerHTML = productName";
document.getElementById("notifyProductName").fadeOut(400);
}
I want to display the productName in a html message box and then fade the message box out after a few seconds.

Set a 3 second setTimeout() function and use a CSS class with transition on opacity for the fade.
cart.prototype.ShowItem = function (productName)
{
var el = document.getElementById("notifyProductName");
el.innerHTML = productName;
el.classList.remove('fade');
el.classList.add('show');
var timeout = setTimeout(function() {
el.classList.add('fade');
}, 3000);
}
.notifyProductName {
opacity: 0;
}
.show {
opacity: 1;
}
.fade {
opacity: 0;
transition: opacity .5s;
}
<div id="notifyProductName" class="notifyProductName"></div>

Related

javascript onclick css fade in each time, not just 1st time

How can I have text fade in on each click and not just the first time using css transition and JavaScript?
Here is what I have so far
<style>
#data {
transition: .7s;
}
</style>
<h1 id="data"></h1>
click 1
document.getElementById('data').style.opacity = 0;
function go(event){
event.preventDefault();
document.getElementById('data').style.opacity = 1;
document.getElementById('data').innerHTML = 'test';
}
document.getElementById('clicker').addEventListener('click', go);
It can also be done using Element.animate():
const dataElement = document.getElementById('data')
dataElement.style.opacity = 0
function go(event) {
event.preventDefault()
dataElement.animate({
opacity: [0, 1]
}, 700).onfinish = () => dataElement.style.opacity = 1
}
document.getElementById('clicker').addEventListener('click', go)
<h1 class="fade-in" id="data">test</h1>
click 1
EDIT:
In the above snippet onfinish event handler was used to maintain the final opacity value since it was being set back to 0 after the animation ends. But I found that this can also be achieved by setting fill: 'forwards' in the keyframe options:
const dataElement = document.getElementById('data')
dataElement.style.opacity = 0
function go(event) {
event.preventDefault()
dataElement.animate({
opacity: [0, 1]
}, {
duration: 700,
fill: 'forwards'
})
}
document.getElementById('clicker').addEventListener('click', go)
<h1 class="fade-in" id="data">test</h1>
click 1
Also you might want to check browser compatibility before implementing those approaches
And if you want a safer approach you may use css animations:
const data = document.getElementById('data')
data.style.opacity = 0
const clicker = document.getElementById('clicker')
clicker.addEventListener('click', () => {
data.classList.remove('fade-in')
data.offsetWidth // required to trigger a reflow and restart the animation
data.classList.add('fade-in')
})
.fade-in {
animation-name: fadein-animation;
animation-duration: 700ms;
animation-fill-mode: forwards;
}
#keyframes fadein-animation {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
<h1 id="data">test</h1>
click 1
setTimeout might work for you. On click set it invisible immediately and use setTimeout to have a delay then show it again.
document.getElementById('data').style.opacity = 0;
document.getElementById('data').innerHTML = 'test';
function go(event){
event.preventDefault();
document.getElementById('data').style.opacity = 0;
setTimeout(() => {
document.getElementById('data').style.opacity = 1;
}, 1000);
}
document.getElementById('clicker').addEventListener('click', go);
#data {
transition: .7s;
}
<h1 id="data"></h1>
click 1
<h1 id="data" style="opacity:0"> </h1>
<button type="button" id="clicker">Fade In</button>
<script>
var data = document.getElementById('data');
function fadeIn(){
data.innerHTML = 'Data entered successfully.';
data.animate({opacity:[0,1]},{duration:400,fill:'forwards'});
}
document.getElementById('clicker').addEventListener('click',fadeIn);
</script>

How to play one css anmation before chaging innerHTML and another one after it?

What I need is this: when I click the button I want the old text to slowly disappear, then I want the new one to slowly appear.
But the disappear animation never gets played. Here's my code:
css
.quote-container {
opacity: 0;
}
.appear {
opacity: 0;
animation: fadeIn 1200ms ease-in forwards;
}
.disappear {
opacity: 1;
animation: fadeOut 1200ms ease-in;
}
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
javascript
let pickARandomQuote = () => {
index = Math.floor(Math.random() * quotes.length);
currentQuote = quotes[index].quote;
currentAuthor = quotes[index].author;
console.log(currentQuote + " \n" + currentAuthor);
let quoteContainer = document.getElementById("quote-container");
quoteContainer.classList.add("disappear");
void quoteContainer.offsetWidth;
quoteContainer.classList.remove("disappear");
void quoteContainer.offsetWidth;
quoteContainer.classList.remove("appear");
document.getElementById("text").innerHTML = currentQuote;
document.getElementById("author").innerHTML = "- " + currentAuthor;
void quoteContainer.offsetWidth;
quoteContainer.classList.add("appear");
return {
quote: currentQuote,
author: currentAuthor
};
};
document.addEventListener("DOMContentLoaded", pickARandomQuote);
let button = document.getElementById("new-quote");
if (button) {
button.addEventListener("click", pickARandomQuote);
}
It seems like the animation on the screen happens independently from the code, so "disappear" animation doesn't have enough time to get played. I tried "setTimeout", but it didn't help though.
You need to wait till disappear animation ends before executing appear.
One of the approaches is setTimeout function.
Example:
let pickARandomQuote = function() {
index = Math.floor(Math.random() * quotes.length);
currentQuote = quotes[index].quote;
currentAuthor = quotes[index].author;
let quoteContainer = document.getElementById("quote-container");
quoteContainer.classList.remove("appear");
quoteContainer.classList.add("disappear");
setTimeout(function () {
document.getElementById("text").innerHTML = currentQuote;
document.getElementById("author").innerHTML = "- " + currentAuthor;
quoteContainer.classList.remove("disappear");
quoteContainer.classList.add("appear");
}, this.duration)
};
document.addEventListener("DOMContentLoaded", { handleEvent: pickARandomQuote, duration: 0 });
let button = document.getElementById("new-quote");
if (button) {
button.addEventListener("click", { handleEvent: pickARandomQuote, duration: 1200 });
}
However, if you can use jQuery, the following Q&A may work for you.
Jquery replacewith fade/animate

Javascript animation fires intermittently

I have a Math game with a function to calculate the correct answer. If user answer correctly I want to show an animated images. I was able to achieve this but the animation it self work basically one time yes and one time not.
Do I miss something?
function checkAnswer() {
// Checks the answer against the first element in
// the returned calculateCorrectAnswer array
let userAnswer = parseInt(document.getElementById('answer-box').value);
let calculatedAnswer = calculateCorrectAnswer();
let isCorrect = userAnswer === calculatedAnswer[0];
if(isCorrect) {
incrementScore();
moveRight();
} else {
alert(`Awwww .... you answered ${userAnswer}. the correct answer was ${calculatedAnswer[0]} 😟`);
incrementWrongAnswer();
}
runGame(calculatedAnswer[1]);
}
function moveRight() {
let theImg = document.getElementById('myImg');
let msg = document.getElementById('message');
theImg.classList.toggle('fade-in');
msg.classList.toggle('fade-in');
}
// My CSS
#myImg.fade-in {
animation-name: fadeIn;
animation-duration: 2s;
}
#keyframes fadeIn {
0% {opacity: 0;}
100% {opacity: 1;}
}enter code here
In your case I'd use transition, instead of animation
The code would look like that:
#myImg {
opacity: 0;
transition: opacity 2s linear;
}
#myImg.fade-in {
opacity: 1;
}
find the solution, basically just removing the class and add again :)
function moveRight() {
let theImg = document.getElementById('myImg');
let msg = document.getElementById('message');
theImg.classList.remove('fade-in');
void theImg.offsetWidth;
theImg.classList.toggle('fade-in');
msg.classList.remove('fade-in');
void msg.offsetWidth;
msg.classList.toggle('fade-in');
}

Animation: Fade in when creating an element and fade out when deleting

I'm having trouble with the following situation.
I have a button which acts like a normal toggle. When I click on the "Animate" button, I want the <p>This is new Div</p> to fade in when I again click on the Animate button, this <p> should fade out.
How can I achieve this?
const main = document.getElementById('main');
const btn = document.getElementById('btn');
let show = false;
btn.addEventListener('click', () => {
if(show) {
const newDiv = document.getElementById("new-div");
newDiv.remove();
show = false;
} else {
const newDiv = document.createElement('div');
newDiv.id = "new-div";
newDiv.innerHTML = "<p>This is new Div</p>";
main.appendChild(newDiv);
show = true;
}
})
#new-div {
transition: all 2s ease-in-out;
}
<div id="main">
<button id="btn">Animate</button>
</div>
I'm actually building a gallary layout app, which requires to fade in when clicked on a image + show in full screen, then fade out to its original position when clicked. Since there will be many images, I want to use JS to dynamically work on this.
And the biggest hurdle so far is to implement fade-out, because the element is being deleted.
Based on your information I've made a refined version, pls see fiddle and code below: https://jsfiddle.net/Kenvdb/8nsbp16o/
JavaScript:
const main = document.getElementById('main');
const btn = document.getElementById('btn');
let toggledDiv = null;
btn.addEventListener('click', () => {
if (!toggledDiv) {
show();
} else {
hide();
}
})
const show = () => {
toggledDiv = document.createElement('div');
toggledDiv.id = "content";
toggledDiv.style.opacity = "1";
toggledDiv.innerHTML = "<p>This is new Div</p>";
main.appendChild(toggledDiv);
}
const hide = () => {
toggledDiv.style.animation = "fade-out 0.5s ease-in";
toggledDiv.style.opacity = "0";
toggledDiv.addEventListener('animationend', remove);
toggledDiv.addEventListener('webkitAnimationEnd', remove);
}
const remove = () => {
toggledDiv.remove();
toggledDiv = null;
};
CSS:
#content {
opacity: 0;
animation: fade-in 0.5s ease-in;
}
#keyframes fade-in {
0% { opacity: 0; }
100% { opacity: 1; }
}
#keyframes fade-out {
0% { opacity: 1; }
100% { opacity: 0; }
}
HTML:
<div id="main">
<button id="btn">Animate</button>
</div>
You'll need to set the opacity to 0 first. Then you can apply a keyframe animation.
Otherwise, the element has nothing to transition from.
See below.
#new-div {
opacity: 1;
animation: fadeIn 2s ease-in-out;
}
#keyframes fadeIn {
from {
opacity: 0;
}
}
There's several ways of doing this. You can set the opacity of the newly added element using the style attribute:
const main = document.getElementById('main');
const btn = document.getElementById('btn');
let show = false;
let fading = false;
btn.addEventListener('click', () => {
if (fading) return;
if (show) {
const newDiv = document.getElementById("new-div");
newDiv.style = "opacity: 0"; // start the fade
fading = true;
window.setTimeout(function() {
fading = false; // disable showing/hiding while fading
newDiv.remove(); // remove after fade completed
show = false;
}, 2000);
} else {
show = true;
const newDiv = document.createElement('div');
newDiv.id = "new-div";
newDiv.innerHTML = "<p>This is new Div</p>";
main.appendChild(newDiv);
window.setTimeout(function() {
newDiv.style = "opacity: 1"; // Start fading after a minimal time
});
}
})
#new-div {
transition: all 2s ease-in-out;
opacity: 0;
}
<div id="main">
<button id="btn">Animate</button>
</div>
Or you can use jQuery, which significantly reduce the code:
$("#btn").on('click', () => {
var newDiv = $("#new-div");
if (newDiv.length) {
newDiv.stop().fadeOut(2000, function() {
newDiv.remove();
});
} else {
$(`<div id='new-div'>
<p>This is new Div</p>
</div`).appendTo("#main").hide().fadeIn(2000);
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="main">
<button id="btn">Animate</button>
</div>
You can do it simply using both of fadeIn() and fadeOut() methods in jQuery.
Here is an example:
let alreadyClicked = false;
$("#btn").click(function() {
if(alreadyClicked == false) {
$("p").remove(); //Remove the paragraph if already created.
$("#main").append("<p style='display: none;'>Hello, world!</p>"); //Create a paragraph.
$("p").fadeIn(); //Show it by fading it in.
alreadyClicked = true;
} else {
$("p").fadeOut(); //Fade it out
alreadyClicked = false;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="main">
<button id="btn">Animate</button>
</div>

How to fade in and out one by one using css animation and angular?

Consider the following plunker
I have a list of tile that I want to fade in one by one using ng-repeat however the animation fade the entire tile set all together.
Here is my CSS
.fade-up {
animation: fadeUpIn 5s ease-in-out;
}
.fade-in {
animation: fadeUpOut 5s ease-in-out;
}
#keyframes fadeUpIn {
0% {
opacity: 0;
transform: translate3d(0, 100%, 0);
}
100% {
opacity: 1;
transform: none;
}
}
Here is my template:
<div ng-controller="baseController as bCtrl">
<button ng-click="bCtrl.toggleStuff()">
Toggle
</button>
<div ng-repeat="group in bCtrl.groupList">
<div class="tile-style"
ng-repeat="tile in group"
ng-class="{'fade-up': bCtrl.display, 'fade-in': !bCtrl.display}">
{{tile}}
</div>
</div>
</div>
Here is my JS
function toggleStuff() {
self.display = !self.display;
}
Is there a way to fade in the tiles individually?
u want it animate one by one, an easy way is to set them to display one by one, custom ng-animate might cost more
u may need to record timeouts and clear when change happen during loop
for (var i = 0; i < 10; i++) {
(function(a) {
setTimeout(function() {
console.log(a); //0,1,2...
//$scope.list[a].display = false;
//$scope.$apply()
}, i * 1000);
})(i)
}
As the other answer suggests, you could do this adding timeouts.
I have applied the solution in your plunker.
http://plnkr.co/edit/RV6E20IP5VLrMDKkOr4G?p=preview
for (var i = 1; i < 26; i++) {
tile = { val: i , display: false };
if (i % 4 == 0){
tempList.push(tile);
self.groupList.push(tempList);
tempList = []
} else {
tempList.push(tile);
}
(function(index, tile) {
$timeout(function() {
tile.display = true;
}, i * 400);
})(i, tile);
}

Categories