Typing and deleting letters of a word in the JS

type

I just want to make something for practice like above typing a word. I stumbled upon:
https://mattboldt.com/demos/typed-js/

But I do not want to use the library. Can we also do this on our own?

I tried something here, but it is far too tangent from what I anticipate

I am not asking someone to write full code, but can some one guide me on what to search or in what direction can I move.

I searched for something on codepen also but could not get anything close in vanilla or JQuery either.

If you wanted css practice instead :slight_smile:

5 Likes

Wow, That is too awesome. I am downloading the code on my sublime text, and try to understand it. Thank you so much for your prompt support and instant reply.

Hi there codispoetry,

@PaulOB, as always, pulls magic CSS out of his box of tricks,
whilst I was struggling with just a basic javascript example. :biggrin:

As I managed to code it eventually, I suppose I had better post
it as this thread is still residing in the JavaScript forum. :winky:

<!DOCTYPE HTML>
<html lang="en">
<head>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1">

<title>Untitled document</title>

<!--
The internal CSS should be transferred to an external file
<link rel="stylesheet" href="screen.css" media="screen">
-->

<style media="screen">
body {
    background-color: #f0f0f0;
    font: normal 1em / 1.62em sans-serif;
 } 

#content {
	padding: 0.6em 1em;
	font-size: 1.5em;
}
</style>

</head>
<body>

<div id="content"></div>

<script>
(function( d ) {
   'use strict';

	var c = 0,i = 0, st,
	 text = ['Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
	         'Vivamus tristique libero justo, vitae placerat magna lobortis eget.',
	         'Vivamus felis nunc, egestas a est ac, porta malesuada odio.',
	         'Integer imperdiet sollicitudin odio et congue.'
	         ],
	 cont = d.getElementById( 'content' );

   function typing( c ) {	  
      if ( i === text.length) {
   	       return;
   	    } 
      if ( c < text[ i ].length && i < text.length ) {
           cont.textContent += text[ i ].charAt( c );
           c ++;
    	   st = setTimeout( function(){ typing( c ) },250 ); 
        }
      else {
      	   clearTimeout( st );
      	   cont.textContent = ''; 
      	   c = 0;
      	   i ++ ; 
      	   setTimeout( function(){ typing( c ) }, 250 );
      	}
     }

   typing( c );

}( document ));
</script>  

</body>
</html>

coothead

2 Likes

Thank you so much for writing a code. You are a very helpful and joyful person. I will certainly see your code and try to learn from it.

I have also written something:

<script>
	var typeText = 'Abraham Lincoln';
	var convertArray = typeText.split("");
	console.log(convertArray);
	var timeLoop;

	function textLoop() {
		if (convertArray.length > 0) {
			document.getElementById('type').innerHTML += convertArray.shift();			
		} else {
			document.getElementById('type').innerHTML -= convertArray.pop();
		}
		timeLoop = setTimeout('textLoop()',70);
	}
	textLoop();	
</script>

But I am still unable to delete the Abraham Lincoln text once it is typed.

I started from this tuts:

Live URL

HTML:


	<div class="container">
		<h2>I am <span id="type"></span></h2>
	</div>

once this part is executed:
document.getElementById('type').innerHTML += convertArray.shift();

It becomes an HTML. I think somehow we have to take it back in an array.

Hi there codeispoetry,

I forgot to mention that the code which I posted was
non-JavaScript unfriendly and just work in progress, :wonky:

Here is an updated version which addresses that problem…

<!DOCTYPE HTML>
<html lang="en">
<head>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1">

<title>Untitled document</title>

<!--
The internal CSS should be transferred to an external file
<link rel="stylesheet" href="screen.css" media="screen">
-->

<style media="screen">
body {
    background-color: #f0f0f0;
    font: normal 1em / 1.62em sans-serif;
 } 

#content {
	max-width: 36em;
	padding: 1em;
	margin: auto;
	border: 1px solid #999;
	background-color: #fff;
	font-size: 1em;
}
#content p {
    margin: 0;	
}
.extra {
	font-style: oblique;
	color: #999;
}
</style>

</head>
<body>

<div id="content">
 <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
 <p>Vivamus tristique libero justo, vitae placerat magna lobortis eget.</p>
 <p>Vivamus felis nunc, egestas a est ac, porta malesuada odio.</p>
 <p>Integer imperdiet sollicitudin odio et congue.</p>
</div>

<script>
(function( d ) {
   'use strict';

	var k, c = 0,i = 0, st,
	 text = ['Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
	         'Vivamus tristique libero justo, vitae placerat magna lobortis eget.',
	         'Vivamus felis nunc, egestas a est ac, porta malesuada odio.',
	         'Integer imperdiet sollicitudin odio et congue.'
	         ],
      par = d.querySelectorAll( 'p' );
      
      for ( k = 0; k < par.length; k ++ ) {
      	    par[ k ].textContent = '\u00a0';
         }
   function typing( c ) {	  
      if ( i === text.length) {
   	       return;
   	    } 
      if ( c < text[ i ].length && i < text.length ) {
           par[i].textContent += text[ i ].charAt( c );
           c ++;
    	   st = setTimeout( function(){ typing( c ) }, 150 ); 
        }
      else {
      	   clearTimeout( st ); 
      	   par[i].classList.add( 'extra' );
      	   c = 0;
      	   i ++ ; 
      	   setTimeout( function(){ typing( c ) }, 150 );
      	}
 
	 }

   typing( c );

}( document ));
</script>  

</body>
</html>

coothead

2 Likes

Hi There @coothead
Thank you so much for writing such a code, and your code is a great work to learn and acquire some new knowledge,

But sir irrespective of what I actually posted my agenda was to learn something as in GIF:

  1. Write a character of a word one by one in the forwarding direction, and delete them in the backward direction.

  2. Words will also change after the first word is written and deleted.

And the same process will be repeated for other words stored in an array or maybe some other way.

I was able to write it down for one word in one direction, but could not delete it and also could not further add an additional word to be written and deleted.

When you shift() you are removing the element from the array so after you have shifted them all there is nothing left to work with.:slight_smile: The array is empty.

You then try to pop() an empty array. Even if you did get the last item in the array with pop() it would not rub out the last letter that was just placed. You would want everything in the array apart from the last one and output a smaller and smaller string each time (not just the last item). It may have been easier just to slice strings as in the example from @coothead but I guess you were practicing with arrays.

I made a small codepen trying to follow your rough logic and ended up with this.

It’s not meant as a solution but more to work out what’s happening. I’m sure it could be shortened considerably.

1 Like

Hi there codeispoetry,

bearing in mind that javascript is not really
my forté,I did manage to make an example
for your consideration…

<!DOCTYPE HTML>
<html lang="en">
<head>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1">

<title>Untitled document</title>

<!--
The internal CSS should be transferred to an external file
<link rel="stylesheet" href="screen.css" media="screen">
-->

<style media="screen">
body {
    background-color: #f0f0f0;
    font: normal 1em / 1.62em sans-serif;
 } 

#content {
	  max-width:5em;
    min-height:1em;
	  padding: 1em;
	  margin: auto;
	  border: 1px solid #999;
    border-radius: 0.3em;
	  background-color: #fff;
	  font-size: 2em;
    text-align: center;
    letter-spacing: 0.15em;
}

#content p {
    margin: 0;	
}

.remove-container {
    animation: curtain 2s ease forwards;
}

@keyframes  curtain {
    0% { transform: rotateX(  0deg );}
 99.9% {border: 1px solid #999;}
  100% { transform: rotateX( 90deg );border: 0;} 
}
</style>

</head>
<body>

<div id="content">
 <p>The Quick Brown Fox Jumps Over The Lazy Dog</p>
</div>

<script>
(function( d ) {
   'use strict';

	var c = 0, i = 0, st, st1,speed = 350,
	 text = 'The Quick Brown Fox Jumps Over The Lazy Dog',
    con = d.querySelector( '#content' ),
    par = con.querySelector( 'p' );
    par.textContent = '';

   function typing( c ) {	

      par.textContent += text.charAt( c );

      if ( ( text.charAt( c ) === ' ' ) || ( text.charAt( c ) === '') ){
             text = text.replace( par.textContent,'' );
             clearTimeout( st );        
             return removeText( i, c );
        }

      else {
           c ++;
    	     st = setTimeout( 
            function(){
              typing( c );
            }, speed );
        }         
	    }

function removeText( i, c ) { 

   if ( i <= c ) {  
        par.textContent = 
        par.textContent.substring( 1 );
        i ++;
        st1 = setTimeout( 
          function(){ 
            removeText( i, c ); 
          }, speed );
       }

   else {
        clearTimeout( st1 ); 
        i = 0; 
        c = 0; 
        typing( c );
       }

    if ( c === text.length) {
         clearTimeout( st );
         clearTimeout( st1 );
         con.classList.add( 'remove-container' );
         return;
       }
     }

   typing( c );

}( document ));
</script>  

</body>
</html>

You can also have a quick peep at it here…

Full Page View:-
https://codepen.io/coothead/full/jOVmrBY

coothead

2 Likes

Your JS skills are miles better than mine.

This took me all afternoon :slight_smile:

2 Likes

Well, I am definitely not a @Paul_Wilkins,
it took me all day to finally get it working. :eek:

coothead

4 Likes

I was thinking that some other work would be impenetrable. Plugging away at it with enough solutions to different problems though has ended up surprising and scaring myself at the progress that can be made.

The real breakthrough came when I actively stopped procrastination, by using a new thread to guide others through the process, as an excuse to make progress on the matter :slight_smile:

2 Likes

The J > -1 What is the mathematical logic behind assigning inistial value to J>-1?

I am facing mental difficulty in undersatnding this logic:

if (j > -1) {
      myElement.innerHTML = convertArray.join("");
      console.log()
      if (j > 0) {
        convertArray.pop();
      }
      j--;
      if (j === -1) {
        convertArray = typeText[counter].split("");
        i = 0;
      }
    }

It’s much the same (but in reverse) as using the array.length number which gives you the number of items which is one more than the position in the array as the array starts from zero. When reducing the array zero will be the first item in the array so I had to check for -1 to know that it had completed its journey.

When the array reaches -1 we can’t pop any more because the array is empty and in order to reverse the process I refill the array with the original values and then it all starts again :slight_smile:

Not very elegant I know but it does its job:) I’m sure there is an easier logic just waiting to jump out at me :wink:

1 Like

:heavy_check_mark:

I just checked the code and it seems that you are using i for when counting forward, and j for when counting backwards.

A possibly easier solution is to use only one variable called pos, and an increment variable that switches from +1 to -1 instead.

Step 1: Rename i to pos
Step 2: Use pos += increment and invert increment when bounds are reached
Step 3: Check if increment is >0 or <0 for each if statement
Step 4: Replace j with pos instead.
Bonus step: replace -1 checks with suitable 0 checks instead, for added clarity.

    var pos = 0;
    var increment = 1;
    //...
     if (increment > 0 && pos < convertArray.length) {
      myElement.innerHTML += convertArray[pos];
      pos += increment;
      if (pos === convertArray.length) {
        increment = -increment;
      }
    }
    if (increment < 0 && pos >= 0) {
      myElement.innerHTML = convertArray.join("");
      if (pos > 0) {
        convertArray.pop();
      }
      pos += increment;
      if (pos < 0) {
        convertArray = typeText[counter].split("");
        pos = 0;
        increment = -increment;
      }
    }

That is an improvement. Further improvements can be made from there too :slight_smile:

2 Likes

I think JS is pretty straight, but most of the time it is the mathematical logic, and flow chart of logic that needs our energies.

I tend to disagree about needing more energies. Whenever something starts to be complex, there are almost always techniques that can be used to make it simpler and easier.

Some call it lazy, others call it efficnentefficnent.<backspace fail> something else instead.

2 Likes

True, actually that is how Hypothesis work in scientific exploration also. If some thing deosnt work either discard or tweak the Hypothesis.

For me the real breakthrough came when I understood that debugging your own code is several more times difficult than it was to write the code.

That has a major impact when you write code at the limit of your ability. Debugging that code then becomes highly difficult indeed. The remedy is to use techniques that leave yourself plenty of headroom, so that debugging becomes a lot easier later on too.

Simple and easy tend to be frowned upon by people intent on pushing their muscles. There’s more going for it than at first thought.

2 Likes