DataCent
DataCent

Reputation: 59

Removing alert() function crashes my code

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

Answers (3)

Kosh
Kosh

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

Barmar
Barmar

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

Andam
Andam

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

Related Questions