Make a Header disappear and reappear after waiting 2 seconds - javascript

I ANSWERED DOWN BELOW
I want to make the header of my document once scrolled play an animation to fade and then use style.display to make it unusable. Here is the code:
<script type="text/javascript">
function Scroll()
{
var head = document.getElementById('header')
if (window.pageYOffset > 1)
{
head.style.display = "none";
head.style.opacity = "0";
} else {
head.style.display = "block";
head.style.opacity = "1";
}
}
window.addEventListener("scroll",Scroll);
</script>
I don't know how to make this though so that it will wait two seconds before running the document.getElementById('header').style.display = "none".
I have in the <style> tag to do the fade out animation with the .opacity, it is just the .display that I want to make wait the 2 seconds of animation.
Also I have no idea how to use JQuery or other documents' code so I need it to be purely in HTML, JavaScript or CSS. Thanks. (I'm a noob)

If what you need is to run after 2 seconds
For that you can make use of setInterval or setTimeout depending on your needs.
setTimeout(function(){ alert("This is after 3 sec"); }, 3000);
setInterval : Runs after every specified time interval.
setTimeout : Runs only once after waiting specified time.
W3CSchool Doc
If what you need is to wait till the DOM is loaded.
For that you will have to check the event DOMContentLoaded.
whatever the code you have it should be within this.
document.addEventListener("DOMContentLoaded", function (event) {
function Scroll()
{
var head = document.getElementById('header')
if (window.pageYOffset > 1)
{
head.style.display = "none";
head.style.opacity = "0";
} else {
head.style.display = "block";
head.style.opacity = "1";
}
}
window.addEventListener("scroll",Scroll);
}
I hope this solved your problem.

The best way to approach this for performance and maintainability is to let css handle the animation and only use javascript to capture the event and add a class.
Also, you need a way to make sure the function bound to the scroll event only fires once.
Finally, if you want to destroy the element, you can use javascript to listen for the 'animationend' event (the name is browser-dependent), which is captured by the browser, and fire your function to destroy the element at that time (instead of having a fixed 2 second delay as you are trying to do).
Here's a codepen demo of the implementation I just described: http://codepen.io/anon/pen/NdWGqO
Here's the relevant js and css:
//js
var head = document.getElementById('header');
var hasScrolled = false;
function onScroll() { // a function should only start with a capital letter if it is a constructor
if (!hasScrolled) {
head.className += " fade-out";
window.removeEventListener("scroll",onScroll); // remove this so it only fires once
}
hasScrolled = true; // this prevents the class from being added multiple times
}
function destroyElement() {
head.className += " hidden"; // the 'hidden' class will give the element 'display : none'
}
function captureEvents () {
window.addEventListener("scroll",onScroll);
// capture the animation end event, there are better ways to do this to support all browsers FYI
head.addEventListener("animationend", destroyElement);
head.addEventListener("webkitAnimationEnd", destroyElement);
head.addEventListener("oanimationend", destroyElement);
head.addEventListener("MSAnimationEnd", destroyElement);
}
document.addEventListener("DOMContentLoaded", captureEvents);
//css
.hidden {
display: none;
}
.fade-out {
animation-name: fadeOut;
animation-duration: 4s;
animation-iteration-count: 1;
animation-fill-mode: forwards;
-webkit-animation-name: fadeOut;
-webkit-animation-duration: 4s;
-webkit-animation-iteration-count: 1;
-webkit-animation-fill-mode: forwards;
}
#keyframes fadeOut {
from {opacity: 1; }
to {opacity: 0; }
}
#-webkit-keyframes fadeOut {
from {opacity: 1; }
to {opacity: 0; }
}

I figured it out... here is the code for js:
<script type="text/javascript">
function Scroll()
{
var head = document.getElementById('header');
var timeOut;
var displayNone = 'head.style.display = "none"'
if (window.pageYOffset < 1)
{
clearTimeout(timeOut);
}
if (window.pageYOffset > 1)
{
timeOut = setTimeout(function(){displayNone}, 2000);
head.style.opacity = "0";
} else {
head.style.display = "block";
head.style.opacity = "1";
stopcount();
}
}
window.addEventListener("scroll",Scroll);
Then in css:
#header
{
height: 100px;
width: 100%;
position: fixed;
background:radial-gradient(circle,#777,#666);
transition:all 0.2s;
}
And finally in HTML:
<header id="header"></header> /* header info goes in here */
idk why but when I set the display none part to a variable it fixed it.

Related

Adding style to CSS classes in Javascript

I am trying to add an animation-play-state style to a CSS class on button click through Javascript but I am not sure where am doing it wrong.
here is what I did.
function play(){
sky.style.animation-play-state: play;
sun.style.animation-play-state: play;
}
function pause(){
sky.style.animation-play-state: pause;
sun.style.animation-play-state: pause;
}
playButton.onclick = play;
pauseButton.onclick = pause;
But am getting this error in my console
Uncaught SyntaxError: Unexpected token ':'
You have to use camelCase to refer to CSS style properties (this is because "-" means minus in JavaScript, so the properties are all mapped to camelCase).
You also need to assign the states with "=" in JavaScript. You're using ":" which is CSS syntax.
The animation play states are also strings, so you have to wrap them in quotes.
And finally, the states you want are actually "running" and "paused", not "play" and "pause".
Here's a working snippet of what you're trying to do:
let sun = document.querySelector("#sun");
let sky = document.querySelector("#sky");
let playButton = document.querySelector("#playButton");
let pauseButton = document.querySelector("#pauseButton");
function play(){
sky.style.animationPlayState = "running";
sun.style.animationPlayState = "running";
}
function pause(){
sky.style.animationPlayState = "paused";
sun.style.animationPlayState = "paused";
}
playButton.onclick = play;
pauseButton.onclick = pause;
#sun, #sky {
padding: 10px;
transform-origin: center;
animation-name: rotate;
animation-duration: 8s;
animation-iteration-count: infinite;
animation-timing-function: linear;
animation-play-state: paused;
}
#keyframes rotate {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
<div style="display: flex">
<div id="sun">Sun</div>
<div id="sky">Sky</div>
</div>
<div>
<button id="playButton">Play</button>
<button id="pauseButton">Pause</button>
</div>
Use running and paused for play and pause:
function Playpause() {
var pauseState = getId.style.animationPlayState === 'paused';
var runState = getId.style.animationPlayState === 'running';
varName.style.animationPlayState = runState ? 'paused':'running';
}
Instead of using two functions for play and pause you can instead create one and use javascript toggle method to toggle the class. And you can define animation state in the class.

Make animation happen when a section is in view using javascript

I am still learning web designing and I wanted to start an animation on a div which is in middle of the page. I searched for it but everywhere I found it using j-query. Is there any way it can be done using pure CSS and JavaScript.
<div>A lot of contents which take whole screen</div>
<div>Section where animation has to happen when come into view</div>
Please help if it can be done using javascript only and if not then what is the easiest way of doing it.
I just searched like you did and found a pure js answer
REFERENCE
var elements;
var windowHeight;
document.getElementById('content').innerText = "A lot of content to fill up the page. ".repeat(500)
function init() {
elements = document.querySelectorAll('.noanimfornow');
windowHeight = window.innerHeight;
}
function checkPosition() {
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
var positionFromTop = elements[i].getBoundingClientRect().top;
//console.log(positionFromTop,windowHeight);
if (positionFromTop - windowHeight <= 0) {
element.classList.add('animateme');
element.classList.remove('noanimfornow');
}
if (positionFromTop - windowHeight > 0) {/*newly added:Edit2*/
element.classList.add('noanimfornow');
element.classList.remove('animateme');
}
}
}
window.addEventListener('scroll', checkPosition);
window.addEventListener('resize', init);
init();
checkPosition();
#keyframes myanim {
from {
opacity: 0;
transform: scale(.7, .7)
}
to {
opacity: 1;
}
}
.animateme {
animation: myanim 5s;
}
.noanimfornow {
opacity: 0;
}
<div id="content"></div>
<div class="noanimfornow">Section where animation has to happen when come into view</div>
First for the div you need animation only when you scroll, set class to noanimfornow ,
Next in js we check the position of scroll, and set the class to animateme when it reaches into view,
We also check any resizing event and start init function if needed in js
finally we put some animation for those in css
This answer does exactly the same as the other answer, but it uses IntersectionObserver
Thus "No need to enter JS on every scroll." - A Haworth's comment
This Code is referred from here
also i have used Tschallacka's edit to remove copy paste (using .repeat(500) in js)
var elements;
var windowHeight;
document.getElementById('content').innerText = "A lot of content to fill up the page. ".repeat(500)
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
const square = entry.target.querySelector('.noanimfornow');
if (entry.isIntersecting) {
square.classList.add('animateme');
return; // if we added the class, exit the function
}
// We're not intersecting, so remove the class!
square.classList.remove('animateme');
});
});
observer.observe(document.querySelector('.animwrapper'));
#keyframes myanim {
from {
opacity: 0;
transform: scale(.7, .7)
}
to {
opacity: 1;
}
}
.animateme {
animation: myanim 5s;
}
.noanimfornow {
opacity: 0;
}
<div id="content"></div>
<div class="animwrapper">
<div class="noanimfornow">Section where animation has to happen when come into view</div>
</div>

How to replay this CSS animation each time a user clicks?

I've created a button that displays the text "Copied!" each time the user clicks on the "Copy" button. The way I've accomplished this is by assigning the animation to the relevant tag and by also using setTimeout to "reset" the animation. This way, when a user clicks the button a second or third time, the animation plays again.
However, I'm certain this is not an ideal solution because if a user clicks before setTimeout finishes, the button 'breaks' until 2500ms have passed. After that, it works again.
How can I refactor the CSS/JS so that the "Copied!" message displays each time the button is clicked? (Without being limited/delayed by a timeout)
const copyURL = () => {
const copyDiv = document.querySelector(".copyAlert")
copyDiv.textContent = "Copied!";
copyDiv.style.animationName = "disappear";
copyDiv.style.animationDuration = "2.5s";
setTimeout(function(){
copyDiv.style.animationName = "none";
}, 2400);
};
.copyAlert {
opacity: 0;
}
#keyframes disappear {
30% {
opacity: 0;
}
60% {
opacity: 1;
}
100% {
opacity: 0;
}
}
<button onclick="copyURL()">Copy</button>
<span class="copyAlert"></span>
1) Use animationend event
2) Use animate class for animation
3) Don't use JS to insert "Copied!" text, just write it in your html
const copyURL = () => {
const copyDiv = document.querySelector('.copyAlert:not(.animate)')
if(copyDiv) {
copyDiv.classList.add('animate');
copyDiv.addEventListener('animationend', () => copyDiv.classList.remove('animate') );
}
};
.animate { animation: disappear 2.5s linear; }
.copyAlert { opacity: 0; }
#keyframes disappear {
30% { opacity: 0; }
60% { opacity: 1; }
100% { opacity: 0; }
}
<button onclick="copyURL()">Copy</button>
<span class="copyAlert">Copied!</span>
If possible try with setTimeOut() function setTimeOut
to change your text from Copy to Copied! [How to change the button text on click for a short duration only using javascript?

Triggering CSS3 Keyframes with javascript multiple times

I am triggering CSS3 Keyframes with javascript but its working for with first call after that any call to that function doesn't animate my div.
Here the Javascript code
function animateShare (imgSrc){
var share = document.getElementById("shareTools");
share.style.animation = "testAnimate 1s ease-in-out 0s"
//shareTools.style.animationPlayState = "running";
}
Sample of the issue (Click red box to preview)
var box = document.getElementById("box");
function animateBox(){
box.style.animation = "box 1s ease-in-out 0s";
}
#box{
background:red;
width:100px;
height:100px;
}
#keyframes box {
50%{width:300px;}
}
<div id='box' onclick='animateBox()'><div>
JSFIDDLE
I want it to animate everytime i call this function.
You can use well known hack: destroy and create element to reset animation.
var box = document.getElementById("box");
function animateBox(){
//destroy and create hack
document.body.removeChild(box);
document.body.appendChild(box);
box.style.animation = "box 1s ease-in-out 0s";
}
#box{
background:red;
width:100px;
height:100px;
}
#keyframes box {
50%{width:300px;}
}
<div id='box' onclick='animateBox()'><div>
In case someone is still interested by this there is another trick that works:
Changing the dataset value to something it has never been, and then use a css matching on that data.
I used this technique when animating the collapsing/uncollapsing of a menu, which of course can happen multiple times. Here's how I did it:
#menu[data-closed^="1"]{
animation:menu_closing;
}
#menu[data-closed^="0"]{
animation:menu_opening;
}
So the animation is based on the first character of the dataset (1 or 0).
Then in the click event that wants to close/open the menu:
var closed = menu_ele.dataset.closed // closed right now
? parseInt( menu_ele.dataset.closed.substr(0,1) )
: 0; // assuming menu is initialized open
var counter = menu_ele.dataset.closed // nb of times the menu was closed or open
? parseInt( menu_ele.dataset.closed.substr(1) )
: 0;
menu_ele.dataset.closed = ''+(1-closed)+(counter+1);
This way the "closed" dataset variable changes like this at every click:
11 (closing for the first time)
02 (reopening for the first time)
13
04
15
06
...
The first digit indicates whether it is currently closed, while all the rest is a counter to make the value new every time.
Think about your code - after first call it does nothing, becouse it already changed animation property of that element.
According to this CSS-Tricks article:
function animateShare (imgSrc){
var share = document.getElementById("shareTools");
share.style.animation = "testAnimate 1s ease-in-out 0s";
shareTools.style.animationPlayState = "paused";
shareTools.style.animationPlayState = "running";
}
add this code in the body section after the element for which the animation is being played-
<script>
document.getElementById('shareTools').addEventListener("animationend", function () {
this.removeAttribute("style");
})
</script>
or if you dont want to remove style attribute ,because you have other css than animation then create a class and add class dynimacally and remove it as above code.
You can reset the animation by just removing the animation property from the styles of the element after the animation has complete - removing the element is unnecessary. In my example, I set the duration in JS, but you could just as easily add an animationend hook to keep it simpler.
JSFiddle
var duration = 1000;
document.getElementById('box').addEventListener('click', function onClick(ev) {
var el = this;
el.style.animation = 'box ' + (duration / 1000 + 's') + ' ease-in-out';
setTimeout(function() {
el.style.animation = ''
}, duration);
});
#box {
background: red;
width: 100px;
height: 100px;
}
#keyframes box {
50% {
width: 300px;
}
}
<div id='box'><div>

Fading in and out with ES6 and CSS3

So I have a function that I'm trying to create the loops through an array to update a div's innerHTML with JavaScript. I was hoping to set the opacity to 0 and then 1 between setting the new data each time, without using jQuery's fadeIn() and fadeOut().
Here is what I have so far. I think I'm very close, but not sure what I'm doing that's slightly off.
Thanks!
slide(index, tweets, element) {
let self = this;
element.innerHTML = data[index].text;
element.style.opacity = 1;
setTimeout(() => {
index++;
element.style.opacity = 0;
setTimeout(self.slide(index, data, element), 2000);
}, 5000);
}
EDIT
I forgot to mention I'm banking on CSS3 for animation by adding a class to my div that changes with this:
transition: opacity 2s ease-in-out;
I don't know how the code you provided relates to the problem at hand, but here's a simple demo on how to fade out, change the text and then fade back in.
You should be able to expand on this for your needs.
var d = document.querySelector("div");
window.addEventListener("load", function() {
d.classList.add("hidden");
});
var i = 0;
d.addEventListener("transitionend", function() {
if (this.classList.contains("hidden")) {
i++;
this.innerHTML = "SUCCESS! ---> " + i;
}
this.classList.toggle("hidden");
});
div {
opacity: 1;
transition: opacity 2s;
}
div.hidden {
opacity: 0;
}
<div>LOADING...</div>
It just adds the hidden class to trigger the fade out and it binds a transitionend handler to change the text and remove the class for the fade in.

Categories