Javascript Appear-Disappear Animation dont work - javascript

I want to make h1 disappear and after 3 sec appear again. It disappears but dont appear again.
Or do i need inline style for it? And any other useful loop for this except if?
let head1 = document.querySelector(".asd")
let head1style = getComputedStyle(head1);
let head1disp = head1style.display;
let changedisp = function() {
if (head1disp === "block") {
head1.style.display = "none";
} else if (head1disp === "none") {
head1.style.display = "block"
} else {
console.log("Something Wrong!")
}
};
setInterval(changedisp, 3000);
h1 {
display: block;
}
<body>
<h1 class="asd">Look at me!</h1>
<script src="app.js"></script>
</body>
</html>

You don't need JavaScript for that in a modern browser. CSS animations with keyframes are fully capable of delivering the same effect:
<style>
#keyframes fade-out-in {
0% {
opacity: 1;
}
25% {
opacity: 0;
}
75% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.box {
animation: fade-out-in 5000ms;
/* wait time at the beginning */
animation-delay: 2000ms;
}
</style>
<div class="box">
Hello World
</div>
You will probably need to adjust the timing. Learn more about CSS keyframe animations in this fantastic article - https://www.joshwcomeau.com/animation/keyframe-animations/

You can use setTimeout to do it once.
const h1 = document.querySelector('h1');
h1.style.display = 'none';
setTimeout(() => h1.style.display = 'block', 3000);
Or you can use setInterval to do it every 3 seconds.
const h1 = document.querySelector('h1');
function switchDisplay() {
if (h1.style.display === 'block') h1.style.display = 'none';
else h1.style.display = 'block';
}
setInterval(switchDisplay, 3000);

Related

How to apply css to the text item of a list in a if condition executed using setTimeout? (Text slider)

I'm trying to display text from a list of texts declared in the script file which I managed to do but now I'm trying to add the animation class(text-anim) to each text every time the inner HTML is updated.
In the below code it is evident the animation is applied only to the first item of the list when the page is loaded.
I guess the class needs to be removed and then added again but nothing has worked so far.
var quotes = [
" The purpose of our lives is to be happy",
"You only live once, but if you do it right, once is enough.",
"Not how long, but how well you have lived is the main thing.",
"web just isn't the same without you.",
"The unexamined life is not worth living."
];
var index = 0;
var len = quotes.length;
var c = true;
function textincoming(){
var element = document.getElementById("dynamic");
element.classList.add('text-anim')
if(index == len)
{
index = 0;
document.getElementById("dynamic").innerHTML = quotes[index];
index++;
}
else
{
document.getElementById("dynamic").innerHTML = quotes[index];
index++;
}
setTimeout(textincoming, 1000);
}
<html>
<head>
<script src="script.js"> </script>
<style>
#dynamic{
font-size:50px;
}
.text-anim{
animation: textIn .5s ease;
}
#keyframes textIn{
0%{
transform: translateY(100%);
}
100%{
transform: translateY(0%);
}
}
</style>
</head>
<body onload="textincoming()">
<p id="dynamic" class="container"> </p>
</body>
</html>
A better way to do this would be to use animationend event:
var quotes = [
" The purpose of our lives is to be happy",
"You only live once, but if you do it right, once is enough.",
"Not how long, but how well you have lived is the main thing.",
"web just isn't the same without you.",
"The unexamined life is not worth living."
];
var index = 0;
var len = quotes.length;
var element = document.getElementById("dynamic");
element.addEventListener('animationend', () => {
element.classList.remove('text-anim');
});
function textincoming() {
if (index === len) {
index = 0;
}
element.innerHTML = quotes[index];
element.classList.add('text-anim');
index++;
}
setInterval(textincoming, 1500);
#dynamic {
font-size: 50px;
}
.text-anim {
animation: textIn .5s ease;
}
#keyframes textIn {
0% {
transform: translateY(100%);
}
100% {
transform: translateY(0%);
}
}
<body onload="textincoming()">
<p id="dynamic" class="container"> </p>
</body>
You can set another setTimeout to remove the class:
var quotes = [
" The purpose of our lives is to be happy",
"You only live once, but if you do it right, once is enough.",
"Not how long, but how well you have lived is the main thing.",
"web just isn't the same without you.",
"The unexamined life is not worth living."
];
var index = 0;
var len = quotes.length;
var c = true;
function textincoming(){
var element = document.getElementById("dynamic");
element.classList.add('text-anim')
if(index == len)
{
index = 0;
document.getElementById("dynamic").innerHTML = quotes[index];
index++;
}
else
{
document.getElementById("dynamic").innerHTML = quotes[index];
index++;
}
setTimeout(function()
{
element.classList.remove('text-anim');
}, 500);
setTimeout(textincoming, 1000);
}
<html>
<head>
<script src="script.js"> </script>
<style>
#dynamic{
font-size:50px;
}
.text-anim{
animation: textIn .5s ease;
}
#keyframes textIn{
0%{
transform: translateY(100%);
}
100%{
transform: translateY(0%);
}
}
</style>
</head>
<body onload="textincoming()">
<p id="dynamic" class="container"> </p>
</body>
</html>

how to add transition animation to this DIV TOGGLE Hid/Show ?

I have this dive the toggle Hide / Show !! ... It works ok , but I would like to know how to add transition animation to the hide/show ?
this is my JS :
function myFunction() {
var x = document.getElementById("clock1");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none" ;
}
You cannot animate the display property. But you can animate the visibility or opacity property in css easily:
// main.html
<div id="clock1" class="hidden">...</div>
// main.css
#clock1 {
visibility: visible;
opacity: visible;
transition: visibility 0s, opacity 0.5s linear;
}
#clock1.hidden {
visibility: hidden;
opacity: 0;
}
// main.js
function myFunction() {
var x = document.getElementById("clock1")
if (x.classList.contains('hidden')) {
x.classList.remove('hidden')
} else {
x.classList.add('hidden')
}
}
Setting display to none will immediately hide the element, which means there is not opportunity for animation/transition of visibility over time.
Perhaps you could consider using opacity instead, to achieve this?
Add the following CSS:
#clock1 {
transition:opacity 1s;
}
Update your JS:
function myFunction() {
var x = document.getElementById("clock1");
// Update opacity rather than display
if (x.style.opacity === "0") {
x.style.opacity = 1;
} else {
x.style.opacity = 0;
}
}
Working jsFiddle here

Changing Text with Fade Javascript Multiple times

I am trying to create my own website, where it has an initial quote in the center:
"Welcome to my website", and when you hover over the menu options, the quote should change.
For example: if I hover over About it could say: "This is my About me Page". (The example is obviously simplified).
HTML Snippet:
About
Contact
Home
<div>
<p>
Welcome to my Website!
</p>
</div>
CSS Snippet:
.fade {
animation: fadein 2s;
}
#keyframes fadein {
from {
opacity:1;
}
50% {
opacity: 0;
}
to {
opacity:1;
}
}
JS Snippet
let myP = document.querySelector('p');
let titleWords = document.querySelector('a.titleAbout');
titleWords.addEventListener('mouseenter', function(){
myP.classList.add("fade");
setTimeout(function(){
myP.innerHTML = "This is my about Me page";
}, 1000);
setTimeout(function(){
text.classList.toggle("fade");
}, 2000);
});
titleWords = document.querySelector('a.titleContact');
titleWords.addEventListener('mouseenter', function(){
myP.classList.add("fade");
setTimeout(function(){
myP.innerHTML = "This is my Contact page";
}, 1000);
setTimeout(function(){
text.classList.toggle("fade");
}, 2000);
});
However - it only does the fade properly the first time I hover over a menu item, the other times it changes the innerHTML, but doesn't fade in and out.
Why exactly is this happening an how can I fix it?
you have not defined the text variable in your javascript. I think you mean myP.classList.toggle("fade");
let myP = document.querySelector('p');
let titleWords = document.querySelector('a.titleAbout');
titleWords.addEventListener('mouseenter', function(){
myP.classList.add("fade");
setTimeout(function(){
myP.innerHTML = "This is my about Me page";
}, 1000);
setTimeout(function(){
myP.classList.toggle("fade");
}, 2000);
});
titleWords = document.querySelector('a.titleContact');
titleWords.addEventListener('mouseenter', function(){
myP.classList.add("fade");
setTimeout(function(){
myP.innerHTML = "This is my Contact page";
}, 1000);
setTimeout(function(){
myP.classList.toggle("fade");
}, 2000);
});
.fade {
animation: fadein 2s;
}
#keyframes fadein {
from {
opacity:1;
}
50% {
opacity: 0;
}
to {
opacity:1;
}
}
About
Contact
Home
<div>
<p>
Welcome to my Website!
</p>
</div>
You can do it shorter and without setTimeout:
let myP = document.querySelector('p');
function show(textToShow){
myP.innerHTML = textToShow;
myP.classList.add("fade");
}
function hide(){
myP.classList.remove("fade");
}
.fade {
animation: fadein 3s;
}
#keyframes fadein {
from {
opacity:1;
}
50% {
opacity: 0;
}
to {
opacity:1;
}
}
About
Contact
Home
<div>
<p>
Welcome to my Website!
</p>
</div>
I have refactored your code to a more generic version, so you can have as many links as you want and do not need to repeat your code. It takes a title attribute from the a tag as text. Maybe this behaves more like you intended, you can play around uncommenting that timeout.
const myPContainer = document.getElementById('pContainer');
const titleWords = document.querySelectorAll('a');
let i;
function attachHandlers(i, elem) {
let timeoutHandle;
const pElem = document.createElement('p');
pElem.innerHTML = elem.getAttribute('title');
myPContainer.appendChild(pElem);
elem.addEventListener('mouseenter', function(){
timeoutHandle = null;
pElem.classList.add("fadein");
});
elem.addEventListener('mouseleave', function(){
// timeoutHandle = setTimeout(() => {
pElem.classList.remove("fadein");
// }, 2000);
});
}
for (i = 0; i < titleWords.length; ++i) {
attachHandlers(i, titleWords[i]);
}
#pContainer {
position: relative;
height: 20px;
}
#pContainer p {
position: absolute;
display: block;
opacity: 0;
}
.fadein {
animation: fadein 2s;
display: block;
}
#keyframes fadein {
from {
opacity: 0;
}
50% {
opacity: 1;
}
to {
opacity: 0;
}
}
About
Contact
Home
<div id="pContainer"></div>

setTimeout not working as intended with css

var myIndex = 0;
var lastIndex = null;
var slides;
window.onload = function ()
{
slides = document.getElementsByClassName("mySlides");
slidePictures();
}
function slidePictures() {
slides[myIndex].style.display = "block";
slides[myIndex].className += " fadeIn";
console.log(slides[myIndex]);
setTimeout(function ()
{
slides[myIndex].className = "mySlides";
console.log(slides[myIndex]);
setTimeout(function ()
{
slides[myIndex].style.display = "none";
console.log("display none");
}, 1000);
}, 2000);
lastIndex = myIndex;
myIndex++;
if (myIndex >= 3)
return;
setTimeout(slidePictures, 4000);
}
.slidesDiv>img {
width: 80%;
height: 80%;
margin-left: 10%;
opacity: 0;
transition: opacity 1s;
}
.fadeIn {
opacity: 1 !important;
transition: opacity 1s;
}
<div class="slidesDiv">
<img class="mySlides" src="//placehold.it/200x80/0fb">
<img class="mySlides" src="//placehold.it/200x80/0bf">
<img class="mySlides" src="//placehold.it/200x80/fb0">
<img class="mySlides" src="//placehold.it/200x80/0fb">
<h1 id="indicator"> Indicator </h1>
</div>
So my issue is that, the image fades in the first time, but then doesn't fade out afterwards, nor does it disappear?
It's definitely problem with the setTimeout functions and I'm wondering what I'm doing/assuming incorrectly.
I edited your code a bit for cleanliness and I also removed the extra transition from .fadeIn as you already had it part of slidesDiv>img.
In your example your program flow is a bit hard to understand, and you are using a lot of variables which are not clear where they come from (like slides and myIndex) so that was part of the reason why it was difficult to figure why it was failing.
Hopefully I understood correctly what you were trying to achieve and the below should work for you. It's definitely not the best in terms of readability and you might be able to extract some of the nested setTimeouts into other functions, but I didn't want to modify too much of your initial code:
var myIndex = 0;
var lastIndex = null;
var slides;
window.onload = function() {
slides = document.querySelectorAll(".mySlides");
slidePictures(slides);
}
function slidePictures(slides) {
var time = 0;
slides.forEach((slide) => {
setTimeout(() => {
slide.style.display = "block";
slide.className += " fadeIn";
setTimeout(function() {
slide.className = "mySlides";
setTimeout(function() {
slide.style.display = "none";
}, 1000);
}, 2000);
}, time);
time += 4000;
});
}
.slidesDiv>img {
width: 80%;
height: 80%;
margin-left: 10%;
opacity: 0;
transition: opacity 1s;
}
.fadeIn {
opacity: 1 !important;
}
Please see this Pen for complete example: http://codepen.io/rarmatei/pen/apramB
var myIndex = 0;
var lastIndex = null;
var slides;
window.onload = function ()
{
slides = document.getElementsByClassName("mySlides");
slidePictures();
}
function slidePictures() {
slides[myIndex].style.display = "block";
slides[myIndex].className += " fadeIn";
console.log(slides[myIndex]);
setTimeout(function ()
{
slides[myIndex].className = "mySlides";
console.log(slides[myIndex]);
setTimeout(function ()
{
slides[myIndex].style.display = "none";
console.log("display none");
// Move indexes here
lastIndex = myIndex;
myIndex++;
}, 1000);
}, 2000);
if (myIndex >= 3)
return;
setTimeout(slidePictures, 4000);
}
.slidesDiv>img {
width: 80%;
height: 80%;
margin-left: 10%;
opacity: 0;
transition: opacity 1s;
}
.fadeIn {
opacity: 1 !important;
transition: opacity 1s;
}
<div class="slidesDiv">
<img class="mySlides" src="//placehold.it/200x80/0fb">
<img class="mySlides" src="//placehold.it/200x80/0bf">
<img class="mySlides" src="//placehold.it/200x80/fb0">
<img class="mySlides" src="//placehold.it/200x80/0fb">
<h1 id="indicator"> Indicator </h1>
</div>
It's pretty hard to tell what you're trying to achieve from your code. I assume that you want the pictures to fade in, and after a certain delay to fade out again?
For that I would highly suggest you to use jQuery. Here's a fiddle I made.
The slidePictures function would now just look like this:
function slidePictures() {
$(".mySlides").each(function(element){
console.log(this);
// 2000 is the duration of the fading in milliseconds
$(this).fadeIn(2000, function(){
// fadeout is delayed 4000 milliseconds
$(this).delay(4000).fadeOut(2000);
});
});
}
If that's not what you need, please provide additional information.
grwag

Jquery script modification to add fade in/out features

Ok so I found this script from a different part of this site:
var divs = ["wrap20", "wrap21", "wrap22"];
var visibleDivId = null;
function toggleVisibility(divId) {
if(visibleDivId === divId) {
visibleDivId = null;
} else {
visibleDivId = divId;
}
hideNonVisibleDivs();
}
function hideNonVisibleDivs() {
var i, divId, div;
for(i = 0; i < divs.length; i++) {
divId = divs[i];
div = document.getElementById(divId);
if(visibleDivId === divId) {
div.style.display = "block";
} else {
div.style.display = "none";
}
}
}
I was able to successfully implement this code to a site which will show various groups of pictures whenever I click on an independent hyperlink.
What part of this code needs to be manipulated in order for the different elements to fade in or out?
Try something like this:
if(visibleDivId === divId) {
$(div).fadeIn(500);
} else {
$(div).fadeOut(500);
}
500 is the number of milliseconds the fading should take.
Here's a working example with Jquery on JSFiddle.
Another possibility would be to use show(500) and hide(500).
UPDATE:
Based on the OP's comments here's a version to achieve such an effect with CSS transitions (another Fiddle):
HTML
Click1
Click2
Click3
<div>
<div class="wraps on" id="wrap20">
Image #1
</div>
<div class="wraps off" id="wrap21">
Image #2
</div>
<div class="wraps off" id="wrap22">
Image #3
</div>
</div>
Javascript
var divs = ["wrap20", "wrap21", "wrap22"];
var visibleDivId = null;
function toggleVisibility(divId) {
if(visibleDivId === divId) {
visibleDivId = null;
} else {
visibleDivId = divId;
}
hideNonVisibleDivs();
}
function hideNonVisibleDivs() {
var i, divId, div;
for(i = 0; i < divs.length; i++) {
divId = divs[i];
div = document.getElementById(divId);
if(visibleDivId === divId) {
div.className = "wraps on";
} else {
div.className = "wraps off";
}
}
}
CSS
.wraps {
width:100px;
height:100px;
display: block;
position: absolute;
top: 60px;
left: 10px;
}
.on {
opacity: 1;
transition: opacity 2s;
z-index: 999;
}
.off {
opacity: 0;
transition: opacity 2s;
z-index: 100;
}
#wrap20 {
background-color:green;
}
#wrap21 {
background-color:blue;
}
#wrap22 {
background-color:red;
}
You don't need the display property here, it's not fit for transitions anyway. You just display all the divs like you want them and use the opacity property to hide and show them. opacity works well with transitions. Transition and opacity for the two states are rolled up in classes so you don't have to set them separately in your javascript.
some-non-descript-user Ok I tried your Jquery fiddle, and that is EXACTLY what I was looking for! Thanks for your patience and time.

Categories

Resources