SetTimeout lags between calls in Firefox - javascript

I'm trying to optimize my code so that I can cycle through images on a splash page quickly and effectively. I've got it looking really smooth on chrome and safari but when I view the splash page on mobile and firefox it bugs out big time
A demo can be found at http://theotherchrisrock.com
I would love to hear your input on how to fix this. Here is the relevant code:
var i = 0
var j = 0
var l = $('.se-pre-con > div').length - 2;
var $pre_con = $('.se-pre-con');
var $di_sum = $('.splash-image:last-child');
var $img_array = [];
for (t = 0; t < l; t++) {
$img_array[t] = $('.splash-image-' + t);
}
function flashanimation() {
if (i < l) {
$img_array[i].addClass('flash');
i++;
flashloop();
} else if (j != 1) {
$di_sum.addClass('di-some');
j = 1
flashloop();
} else {
$pre_con.addClass('nun');
}
}
function flashloop() {
setTimeout(function() {
flashanimation();
}, 300)
}
$(".blinker").removeClass("blinker");
flashloop();
Basically, the goal is to make the image appear for 150ms and then disappear for 150ms and then next image appears and so on finally ending with just a black div. Right now I'm adding a class to each div which triggers this keyframe animation ~
.splash-image.flash {
-webkit-animation:flash 0.15s linear;
animation:flash 0.15s linear;
-webkit-animation-delay:0.15s;
animation-delay:0.15s;
display:block;
opacity:0;
}
#-webkit-keyframes flash {
0% {
opacity:0;
}
1% {
opacity: 1;
}
100% {
opacity:1;
}
}
#keyframes flash {
0% {
opacity:0;
}
1% {
opacity: 1;
}
100% {
opacity:1;
}
}
I would love to hear your input. Thank u for reviewing my question

Related

Continuously changing the width of an element with setInterval( )

So I want to change the width of a span element inside a h1 element that have the textContent changed every 4s with setInterval().I want to do that to add a transition to the width property to fill the space between the h1 and the next word that span will have smoothly.
I tried to get the width of the span with getBoundingClientRect() but that didn't work and when I set the width it remains the width of the first element and it's not changed dynamically as I would want.
Here is the code:
const changingSpan = document.querySelector('.changing-span');
let array = ['best', 'tastiest', 'freshest'];
let count = 0;
setInterval(function() {
count++;
let elementWidth = changingSpan.getBoundingClientRect().width.toString();
if(count === array.length) count = 0;
changingSpan.classList.add('animation-span');
changingSpan.textContent = array[count];
changingSpan.style.width = `${elementWidth}px`;
changingSpan.addEventListener('animationend', function() {
changingSpan.classList.remove('animation-span');
})
}, 4000);
.changing-span {
display: inline-block;
color: #c82929;
transition: width .2s ease;
}
.animation-span {
animation: moveDown .8s ease;
}
#keyframes moveDown {
0% {opacity: 0;
transform: translateY(-50%);
}
100% {
transform: translateY(0);
}
}
<h1 class="first-heading">The <span class="changing-span">best</span> burgers in town.</h1>
consider an animation using max-width:
const changingSpan = document.querySelector('.changing-span');
let array = ['best', 'tastiest', 'freshest'];
let count = 0;
setInterval(function() {
count++;
if (count === array.length) count = 0;
changingSpan.classList.add('animation-span');
changingSpan.textContent = array[count];
changingSpan.addEventListener('animationend', function() {
changingSpan.classList.remove('animation-span');
})
}, 4000);
.changing-span {
display: inline-block;
color: #c82929;
}
.animation-span {
animation: moveDown .8s ease;
}
#keyframes moveDown {
0% {
opacity: 0;
transform: translateY(-50%);
max-width:0;
}
100% {
transform: translateY(0);
max-width:200px; /* a big value here */
}
}
<h1 class="first-heading">The <span class="changing-span">best</span> burgers in town.</h1>
Your code is very good.
But you need to remove 2 rows like below, then you code works well as you want
let elementWidth = changingSpan.getBoundingClientRect().width.toString();
changingSpan.style.width = ${elementWidth}px;
So the answer was posted by Sean above(Thank you). I will put here the code snippet for this in case somebody will search for something similar and will want to do the same thing:
const changingSpan = document.querySelector('.changing-span');
const changingSpanWrapper = document.querySelector('.changing-span-wrapper');
let array = ['best', 'tastiest', 'freshest'];
let count = 0;
changingSpanWrapper.style.width = `${changingSpan.getBoundingClientRect().width.toString()}px`;
setInterval(function() {
count++;
if(count === array.length) count = 0;
changingSpan.classList.add('animation-span');
changingSpan.textContent = array[count];
changingSpan.addEventListener('animationstart', function() {
let elementWidth = changingSpan.getBoundingClientRect().width.toString();
let elementHeight = changingSpan.getBoundingClientRect().height.toString();
changingSpanWrapper.style.width = `${elementWidth}px`;
changingSpanWrapper.style.height = `${elementHeight}px`;
})
changingSpan.addEventListener('animationend', function() {
changingSpan.classList.remove('animation-span');
})
}, 4000);
.changing-span-wrapper {
display: inline-block;
transition: width .2s ease, height .2s ease;
}
.changing-span {
display: inline-block;
color: #c82929;
}
.animation-span {
animation: moveDown 1s ease;
}
#keyframes moveDown {
0% {opacity: 0;
transform: translateY(-50%);
}
100% {
transform: translateY(0);
}
}
<h1 class="first-heading">The <span class="changing-span-wrapper"><span class="changing-span">best</span></span> burgers in town.</h1>

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>

Trying to make a transition with opacity on images

like my title says, I'm trying to make a transition with opacity (0 to 1 with 2secondes interval) on images, but I don't know how to make it.
The transition only works on the first image but not on the others, and I can't figure it out why.
So I hope you'll help me to understand my mistakes, I'm new on javascript. Thank you in advance, here my code
My HTML file :
<img src="img/1.jpg" alt="slide-photo">
My CSS file :
#slideshow-home img {
width: 100%;
opacity: 0;
transition: 1s ease-in-out;
}
My JS file :
var image = document.querySelector('img');
var img = 1 ;
window.setInterval(changeImage, 2000);
function changeImage() {
image.setAttribute('src', 'img/' + img + '.jpg');
image.style.opacity = 1;
img++;
if(img === 6) {
img = 1;
}
}
This is how i handle fade in transitions for images, the benefit is it doesn't start until the image has actually been loaded so it should never be choppy while fading in
JS
var image = document.querySelector('img');
var img = 1;
window.setInterval(changeImage,5000);
function changeImage() {
image.classList.remove('fadeIn')
image.src = 'img/'+img+'.jpg'
img++
if (img == 6) {
img = 1;
}
}
image.addEventListener('load', () => { // This function looks at the image and every time an image is loaded i.e whenever it gets a new src, it does a fade in animation
void(image.offsetHeight)
image.classList.add('fadeIn')
})
CSS
I normally do this with an animation, like below
#slideshow-home img {
width: 100%;
opacity: 0;
}
#keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.fadeIn {
animation:fadeIn 2s forwards;
}

How can I create a CSS animation in JavaScript?

How can I create the CSS animation below in JavaScript? I've looked all over Google, and tried multiple times to create this but I couldn't figure out how to do this.
#keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 100;
}
}
To run this, I know I can use what is shown below, but I don't know how to create this animation. Can anyone help?
element.style.animation = "fadeIn 5s linear";
You can use javascript with transition to achieve it
// start frame
const start = {
opacity: 0
};
// end frame
const end = {
opacity: 1
};
const element = document.querySelector('span');
Object.assign(element.style, start);
element.style.transition = 'all 5s linear';
requestAnimationFrame(() => {
Object.assign(element.style, end);
});
<span>Lorem Ipsum</span>
What do you mean exactly with "Create in Javascript"? Without using CSS?
If so, you can use a simple interval to update the opacity of the element until it reached 0 or 100. Simple example:
let opacity = 0;
const fadeEl = document.getElementById("fadeInElementIdWithOpacity0");
const fadeInInterval = setInterval(() => {
if (opacity < 1) {
opacity = opacity + 0.1
fadeEl.style.opacity = opacity;
} else {
clearInterval(fadeInInterval);
}
}, 200);
You can first define this function with whatever amount of intervals that you want and then call it with any querySelector
function fadeIn(x) {
var fade = document.querySelector(x);
var opacity = 0;
var intervalID = setInterval(function() {
if (opacity < 1) {
opacity = opacity + 0.1
fade.style.opacity = opacity;
} else {
clearInterval(intervalID);
}
}, 200);
}
havnig this function in console and running fadeIn(".-logo") will fade in the stackoverflow's logo

How to hide elements (with smooth transition) by class with javascript?

I have a group of divs that share the same class (optionsclass). The display is set to block. When a user clicks them the following javascript function is executed the display is changed to none.
function hideBlockElementsByClass(className)
{
var elements = document.getElementsByClassName(className);
for(i in elements)
{
elements[i].style.display = "none";
}
}
The transition between display block and none is quite rough and I would like to make a smoother transition. What's the best strategy to accomplish this?
Use CSS3 :
.className {
opacity: 0;
visibility: hidden;
-webkit-transition: visibility 0.2s linear,
opacity 0.2s linear;
-moz-transition: visibility 0.2s linear,
opacity 0.2s linear;
-o-transition: visibility 0.2s linear,
opacity 0.2s linear;
}
.className:hover {
visibility: visible;
opacity: 1;
}
While Sridhar gives a nice CSS3 solution and other mention Jquery.
Here you can find a pure javascript/CSS solution:
https://codereview.stackexchange.com/questions/7315/fade-in-and-fade-out-in-pure-javascript
Try this method
HTML
<div class = "image" onclick = "eff()"></div>
CSS
.transition {
-moz-transition: 2s width;
width: 150px;
height: 100px;
}
Script
function eff() {
var k = document.getElementsByClassName("image");
k[0].className = "transition";
}
try this in plain javascript:(Will work on IE10, chrome, firefox, safari, android, ios)
<script>
function hideBlockElementsByClass(className) {
var elements = document.getElementsByClassName(className);
console.log(elements.length)
for (var i = 0; i < elements.length; i++) {
(function (a) {
elements[a].addEventListener('webkitTransitionEnd', function () {
elements[a].style.display = "none";
}, false);
elements[a].addEventListener('mozTransitionEnd', function () {
elements[a].style.display = "none";
}, false);
elements[a].addEventListener('oTransitionEnd', function () {
elements[a].style.display = "none";
}, false);
elements[a].addEventListener('transitionend', function () {
elements[a].style.display = "none";
}, false);
})(i);
elements[i].style.webkitTransitionDuration = "1s";
elements[i].style.mozTransitionDuration = "1s";
elements[i].style.oTransitionDuration = "1s";
elements[i].style.transitionDuration = "1s";
elements[i].style.opacity = "0";
}
}
</script>

Categories

Resources