I need help identifying and fixing a problem with fade-in text - javascript

I'm creating an introduction page to a little game of mine and I want the text to fade in after a short delay, but it won't appear.
window.onload = function() {
setTimeout(function() {
document.getElementById("welcome").className = "show";
}, 2000);
setTimeout(function() {
document.getElementById("to").className = "show";
}, 2500);
setTimeout(function() {
document.getElementById("title").className = "show";
}, 3000);
setTimeout(function() {
document.getElementById("subtitle").className = "show";
}, 4000);
};
.hide {
opacity: 0;
transition: opacity linear 1s;
}
.show {
opacity: 1;
transition: opacity linear 1s;
} // changed visibility to opacity on Jon Warren's suggestion
<div id="welcome-text">
<span id="welcome" class="hide">Welcome...</span><br/>
<span id="to" class="hide">to</span>
<p id="title" class="hide">[TITLE]</p>
<p id="subtitle" class="hide">a choose your own adventure game.</p>
</div>
I expected the result to be the text fading in one line at a time (the fade provided by my css code, and the actual appearing by the js code) but instead the text gets stuck in the .hide class.
also, is there a way to make the js code more concise?

Firstly, your javascript is a little broken. The semi-colon that you put at the end of your timeouts should actually go outside of the parentheses, like this:
window.onload = function() {
setTimeout(function() {
document.getElementById("welcome").className = "show";
}, 2000);
setTimeout(function() {
document.getElementById("to").className = "show";
}, 2500);
setTimeout(function() {
document.getElementById("title").className = "show";
}, 3000);
setTimeout(function() {
document.getElementById("subtitle").className = "show";
}, 4000);
};
Secondly, visibility isn't a ranging property, meaning that it doesn't know what's in between visible and hidden. You could use opacity though, try this instead:
.hide {
opacity: 0;
transition: opacity linear 1s;
}
.show {
opacity: 1;
transition: opacity linear 1s;
}

Related

Add an addEventListner on a class remove

I made some fandeIn and fadeOut codes to an exercise.
I'm trying to remove the setTimeout() on the fadeIn().
Like using an addEventListner maybe, but there is no transition on .displayNone.
On the MDN I just found transitions interacting with EventListner.
function fadeOut(disable) {
disable.classList.remove('visible');
disable.classList.add('hidden');
disable.addEventListener('transitionend', () => disable.classList.add('displayNone'));
};
function fadein(enable, timer) {
if (!timer) timer = 350;
enable.classList.remove('displayNone');
setTimeout(function () {
enable.classList.remove('hidden');
enable.classList.add('visible');
}, timer);
};
.displayNone {
display: none;
}
.visible {
visibility: visible;
opacity: 1;
transition: opacity 1.5s linear;
}
.hidden {
visibility: hidden;
opacity: 0;
transition: visibility 0s 350ms, opacity 350ms, display 350ms linear;
}
P.S.: This works good, I'm just trying another way to make it works too.
The setTimeout method returns a timeout descriptor/id (actually just an integer). You may use it to remove the timeout later:
// setting timeout
var timeout = window.setTimeout(function(){}, 5000);
window.clearTimeout( timeout )

How can I create an efficient infinitely looping waving text animation?

This is the effect I am trying to create (JSFiddle):
$('.header h1 span').each(function() { // each letter is contained inside a <span> element
var that = $(this);
setTimeout(function() {
that.animate({
top: "-10px"
}, animateTime / 2)
.animate({
top: "10px"
}, animateTime / 2);
}, that.index() * 100);
});
Result:
It appears to be successful. However, I ran into the problem of it looking like this after switching tabs, then coming back:
In the fiddle above, I've tried to "fix" this by making the animation stop when the tab is unfocused. It's better than when I WASN'T checking for tab unfocusing, but it still has problems. This is the code I'm using to do that:
var running = true;
document.addEventListener('visibilitychange', function(){
console.log("Running:" + running);
running = !document.hidden;
if(!running) clearQueues();
})
If the user spends less than a couple seconds unfocused from the tab, the animation looks like the second GIF again, and I don't see a way to avoid that. I've tried using requestAnimationFrame() but I can't figure out how to make it behave correctly.
So, my question is: how do I prevent the animation from being affected by the tab being unfocused?
Bonus points (figuratively) if you can help me make it more efficient on mobile, too.
I'm not sure if this solves the stuttering for you or not. This strategy is similar in concept to what you are doing, but uses CSS animation rather than js.
(function(){
var el = document.querySelectorAll(".wavey")[0];
var oldText = el.innerText
var newHtml = "";
for (var i in el.innerText) { newHtml += ("<span style='animation-delay: " + i/10 + "s;'>" + oldText[i] + "</span>"); }
el.innerHTML = newHtml;
})();
#keyframes wave {
from { transform: translateY(0); }
to { transform: translateY(-1em); }
}
h1.wavey { margin-top: 2em; }
h1.wavey span {
display: inline-block;
animation-duration: 1s;
animation-name: wave;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-timing-function: ease-in-out;
}
<h1 class="wavey">Hello World</h1>

How to remove a div with fade out effect in JavaScript?

I want to remove a div element on click event but i want to remove it with a fade out effect. I have got some JQuery solution but i need pure JavaScript or css solution.
document.querySelector('.list').addEventListener("click", function(e){
if (e.target.localName === "span") {
var removeTarget = e.target.parentNode.parentNode;
removeTarget.parentNode.removeChild(removeTarget);
};
});
This code is removing the div element with no effect. How can i add a fade out effect?
I've made this function a while ago for a personal project:
function removeFadeOut( el, speed ) {
var seconds = speed/1000;
el.style.transition = "opacity "+seconds+"s ease";
el.style.opacity = 0;
setTimeout(function() {
el.parentNode.removeChild(el);
}, speed);
}
removeFadeOut(document.getElementById('test'), 2000);
There are two ways you can achieve this: CSS3 animation or jQuery animation.
CSS3 Animation
In your CSS document, add:
.list {
opacity: 1;
-webkit-transition: opacity 1000ms linear;
transition: opacity 1000ms linear;
}
This will make any change of opacity to your item fade by 1000ms.
Change line 4 of your JavaScript to:
removeTarget.style.opacity = '0';
setTimeout(() => removeTarget.remove(), 1000);
This will make your item change opacity to 0, thus making the transition from step 1 have an effect. Then it will remove the item with your code after 1000ms.
Note: Make sure the time of the CSS3 transition and the setTimeout are the same.
jQuery Animation
Get jQuery
Go to the jQuery Website and download it, or
Add ` in your HTML document before any jQuery code.
Change line 4 of your Javascript to:
removeTarget.fadeOut(1000)
This will Fade Out your item by 1000ms, you can change this time to whatever you want.
In 2020 you can forgo use of use setTimeout for the animationend event, removing the need to maintain the duration in two places:
.fade-out {
animation: fade 2s;
-webkit-animation: fade 2s;
-moz-animation: fade 2s;
}
/* Animate opacity */
#keyframes fade {
from { opacity: 1 }
to { opacity: 0 }
}
#-moz-keyframes fade {
from { opacity: 1 }
to { opacity: 0 }
}
#-webkit-keyframes fade {
from { opacity: 1 }
to { opacity: 0 }
}
const elementToFade = document.getElementById('my-element');
elementToFade.onanimationend = (e) => {
if (e.target.classList.contains('fade-out')) {
elementToFade.parentNode.removeChild(elementToFade);
}
};
// To fade away:
elementToFade.classList.add('fade-out');
It's a good question, but to animate some element in html, this element has to exist while it is animating. So, you have some ways to do this, a good way is hide this element with CSS and after the animation you remove this element. While you hiding you can animate, you can see this example:
<style>
.hide{
opacity: 0;
}
.fade-out {
transition:1s linear all;
}
</style>
<span class="list fade-out">
This is a List, click me to hide
</span>
<script>
document.querySelector('.list').addEventListener("click", function(e) {
if (e.target.localName === "span") {
//Add CSS hide and animate with fade out
var currentCSS = this.className;
this.className = currentCSS + ' hide';
var removeTarget = e.target.parentNode.parentNode;
setTimeout(function(){
removeTarget.parentNode.removeChild(removeTarget);
},1000);
};
});
</script>
Add the following CSS class to the element using elem.className="my-animation"; on click:
.my-animation {
animation: fade 3s steps(90) forwards;
-webkit-animation: fade 3s steps(90) forwards;
-moz-animation: fade 3s steps(90) forwards;
}
#keyframes fade {
from {
opacity: 1;
}
to {
opacity: 0.0;
}
}
You may control the speed of the animation by modifying the steps(number) as well.
Just goto jQuery source code, take out the fade code which is in pure javascript, and use it, no need to reinvent the wheel,
or a hint is reduce the height of div to 0 slowly using setTimeInterval()
or a css solution would be to use transform and transition properties

Callback after the style has been rendered

All non-transition styles should be applied and rendered before applying transition styles. That's why such callback should exist.
demo
<button class="toggle">toggle</button>
<div class="overlay"></div>
.overlay {
width : 400px;
height : 400px;
background : gray;
display : none;
opacity : 0;
transition : opacity 0.3s ease-in-out;
}
.overlay.visible {
opacity : 1;
}
var overlay = $(".overlay");
$(".toggle").click(function() {
if (overlay.hasClass("visible")) {
overlay.removeClass("visible").one("transitionend", function () {
overlay.css("display", "none");
});
} else {
overlay.css("display", "block");
setTimeout(function () {
overlay.addClass("visible");
}, 0);
}
});
You can see that gray block fades smoothly in chrome, but it jumps in firefox.
setTimeout(function () {
}, 0);
Zero timeout is not enough for firefox. I've checked that at my machine 5 miliseconds works fine 50/50.
Should I contact the fathers of this pain or there are any solutions?
Yes, on firefox and IE you need to use getComputedStyle additionaly
var el = overlay[0];
el.style.display = 'block';
// force reflow
getComputedStyle(el).width;
setTimeout(function() {
overlay.addClass("visible");
}, 0);

Changing font colors after certain time duration

I want to put some text on a website, such that it changes color onmouseover and returns to the original color onmouseout after some (say 2 seconds) time delay.
Is it possible to do it using JavaScript?
With jQuery you can do something like this (JSFiddle here)
HTML:
<a id='v1'>Hello</a>​
JS:
​setTimeout(function() {
$('#v1').css('color','#777');
}​,2000);​
Edit: Full JSFiddle example here
JS:
$('#v1').hover(function() {
$(this).css('color','#777');
}, function() {
setTimeout(function() {
$('#v1').css('color','#000');
},2000);
});
​
this kind of features should be provided by CSS3 where available, without involving setTimeout's or other kind of javascript. So, assuming you will choose one of previous proposed Javascript solution for IE, simply use this CSS for every other modern browser
html/css
<span>hover me</span>
span {
color : green;
-webkit-transition : color 2s linear;
-msie-transition : color 2s linear;
-moz-transition : color 2s linear;
-o-transition : color 2s linear;
transition : color 2s linear;
}
span:hover {
color : red;
}
Add onmouseout="timedFunction()" to your text, using this function:
function timedFunction{
var timeout = setTimeout("changeColor()",timeInMilliseconds);
}
Here is a working example using setTimeout;
css:
.text {
color: red;
}
.text.hover {
color: yellow;
}
javascript:
var timeoutId = null;
$(".text").hover(function() {
if (timeoutId != null) {
clearTimeout(timeoutId);
timeoutId = null;
}
$(this).addClass("hover");
}, function () {
var $element = $(this);
timeoutId = setTimeout(function() {
$element.removeClass("hover");
}, 500);
});​
And here is the jsfiddle: http://jsfiddle.net/9TJfD/8/

Categories