user683016 user683016 -4 years ago 99
HTML Question

Why it printing last element

I'm trying this javascript code

var txt = "", txtLen = 0, elem='';
var speed=90;

function write( obj ) {
txt = obj.str;
speed = obj.speed;
elem = obj.elem;
txtLen = txt.length;
setTimeout("loop()", 300);
}
var c=0;
function loop() {
if( c <= txtLen ){
document.getElementById(elem).innerHTML+=txt.charAt(c);
c++;
setTimeout("loop()", speed);
} else {
c=0;
}
}


but in html when i call write function two time its prints only last one, like this-

<font id="o"></font><br>
<font id="oo"></font>
<script>
write({
elem:'o',
speed:90,
str:'Hello'
});
write({
elem:'oo',
speed:90,
str:'World'
});

</script>


Can anyone tell me please, where the error is??

Answer Source

Because you are executing the printing asyncronously, so when you print the first one, the second one already modified your vars.

What you are facing is called impure functions.

Impure functions

All of them which modifies its external environment, usually called side effect.

Any function that uses a non-local variable is potentially impure, for example:

function impure(x) { return x + a; }

The idea to solve it is transform your impure functions into pure functions. What does it mean? A pure function is a function which does not modify its external enviromnent.

Pure functions

All of them which does not modify its external environment, for example:

function pure(x, a) { return x + a; }

Below you have your example working:

<font id="o"></font>
<br>
<font id="oo"></font>
<script>
  function write( obj ) {
      setTimeout(() => {
        loop(obj, 0);
      }, 300);
  }

  function loop(obj, c) {
    if( c <= obj.str.length ){
        document.getElementById(obj.elem).innerHTML += obj.str.charAt(c);
        setTimeout(() => {
          loop(obj, c + 1);
        }, obj.speed);
    }
  }
  
  write({ 
   elem:'o', 
   speed:90,
   str:'Hello'
  });
  
  write({
   elem:'oo',
   speed:90,
   str:'World'
  });

</script>

As you see, loop function takes nothing from its external environment any more. Sharing vars is not a good option when you are working asyncronously.

Hope It helps you.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download