Reputation: 59
I try to create a running infotext on an infoscreen. The Text starts running from the right corner of the screen and leaves on the left side. This process repeats without a limit recursively.
Everything seems to work great, but when I remove the alert after debugging, the text don't start running from the right corner but from the left. Also the programm runs only one time.
HTML:
function setStaticData() {
sessionStorage.setItem('headerWidth', document.getElementById('header').scrollWidth);
}
function getStaticData() {
return sessionStorage.getItem('headerWidth');
}
function animation() {
//get element, its width & time param
var header = document.getElementById('header');
var headerWidth = getStaticData();
var headerTime = header.innerHTML.length * 0.3;
var windowWidth = window.innerWidth;
//clean all
header.style.transition = 'none';
header.style.marginLeft = windowWidth + 'px';
alert("baba"); //BAD BOY
//animate text
header.style.transition = 'margin linear ' + headerTime + 's';
header.style.marginLeft = '-' + headerWidth + 'px';
//wait and repeat
var delay = headerTime * 1000 + 1000;
setTimeout(animation, delay);
}
//first call
window.onload = function() {
setStaticData();
animation();
};
html {
width: 100%;
overflow: hidden;
}
body {
height: 100%;
width: 100%;
position: relative;
display: block;
margin: 0;
padding: 0;
top: 50vh;
transform: translateY(-50%);
color: black;
background-color: #bbc8d9;
}
header {
font-family: calibri, arial;
font-weight: 400;
font-size: 100px;
white-space: nowrap;
}
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
</head>
<body>
<header id="header">+++ News, More News, Another Thing & something else +++</header>
<script src="functions.js"></script>
</body>
</html>
If I remove the bad boy [alert("baba");] it doesn't work, like I mentioned above.
I going crazy! Can you pls help me?
Upvotes: 2
Views: 81
Reputation: 18378
Please look at the snippet below. I don't use sessionStorage
as it is designed for a different purpose. I don't use setTimeout
to wait for the styles to be applied.
I start the animation then restart it on transitionend
event.
window.onload = function() {
var header = document.getElementById('header');
animation();
header.addEventListener('transitionend', function() {
header.style.transition = 'none';
header.style.transform = 'translateX(0)';
animation();
});
function animation() {
var t = header.offsetWidth / 70,
tx = header.scrollWidth;
header.style.transition = 'transform ' + t + 's linear';
header.style.transform = 'translateX(-' + tx + 'px)';
}
};
html {
width: 100%;
overflow: hidden;
background-color: #bbc8d9;
}
header {
font: 100px sans-serif;
white-space: nowrap;
padding-left: 100%;
}
<header id="header">+++ News, More News, Another Thing & something else +++</header>
Upvotes: 0
Reputation: 780724
The problem is that changes to the style of an element are not processed until the Javascript returns to the main event loop and the page is rendered. If you make two assignments to a style, the browser only sees the final result. So when you set marginLeft
to the window width and then set it to "-" + headerWidth + "px"
, only the second change is processed, so that's where the animation starts from.
The alert()
causes the page to be rendered while it's waiting for your response (although I think this may be browser-dependent), which is why it works with that.
A simple solution is to put the second assignment in a setTimeout()
, so it will be executed asynchronously after returning.
function setStaticData() {
//sessionStorage.setItem('headerWidth', document.getElementById('header').scrollWidth);
}
function getStaticData() {
return document.getElementById('header').scrollWidth; //sessionStorage.getItem('headerWidth');
}
function animation() {
//get element, its width & time param
var header = document.getElementById('header');
var headerWidth = getStaticData();
var headerTime = header.innerHTML.length * 0.3;
var windowWidth = window.innerWidth;
//clean all
header.style.transition = 'none';
header.style.marginLeft = windowWidth + 'px';
//alert("baba"); //BAD BOY
//animate text
setTimeout(function() {
header.style.transition = 'margin linear ' + headerTime + 's';
header.style.marginLeft = '-' + headerWidth + 'px';
}, 0);
//wait and repeat
var delay = headerTime * 1000 + 1000;
setTimeout(animation, delay);
}
//first call
window.onload = function() {
setStaticData();
animation();
};
html {
width: 100%;
overflow: hidden;
}
body {
height: 100%;
width: 100%;
position: relative;
display: block;
margin: 0;
padding: 0;
top: 50vh;
transform: translateY(-50%);
color: black;
background-color: #bbc8d9;
}
header {
font-family: calibri, arial;
font-weight: 400;
font-size: 100px;
white-space: nowrap;
}
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
</head>
<body>
<header id="header">+++ News, More News, Another Thing & something else +++</header>
<script src="functions.js"></script>
</body>
</html>
Upvotes: 2
Reputation: 2167
Ok I think i fixed it. Its the timing problem just delay the animate call. 1s
function animation() {
//get element, its width & time param
var header = document.getElementById('header');
var headerWidth = getStaticData();
var headerTime = header.innerHTML.length * 0.3;
var windowWidth = window.innerWidth;
//clean all
header.style.transition = 'none';
header.style.marginLeft = windowWidth+'px';
// delay it for 1000ms
setTimeout(
function(){
//animate text
header.style.transition = 'margin linear '+headerTime+'s';
header.style.marginLeft = '-'+headerWidth+'px';
//wait and repeat
var delay = headerTime * 1000 + 1000;
setTimeout(animation, delay);
}, 1000);
}
Upvotes: 0