Create a seamless typing effect in JavaScript that loops indefinitely

I've managed to tweak this code I stumbled upon to almost perfectly fit my needs, except for one thing - it keeps looping. I just want it to type "zero", delete it, and then type "one" before stopping. I've tried making some adjustments here and there, but I can't seem to get it to function the way I want.

    <span
     class="txt-rotate"
     style="font-size: 72px; font-weight: 500; line-height: 72px; margin-bottom: 20px; color: white;"
     data-period="2000"
     data-rotate='[ "zero.", "one." ]'></span>

<script>
var TxtRotate = function(el, toRotate, period) {
  this.toRotate = toRotate;
  this.el = el;
  this.loopNum = 0;
  this.period = parseInt(period, 10) || 2000;
  this.txt = '';
  this.tick();
  this.isDeleting = false;
};

TxtRotate.prototype.tick = function() {
  var i = this.loopNum % this.toRotate.length;
  var fullTxt = this.toRotate[i];

  if (this.isDeleting) {
    this.txt = fullTxt.substring(0, this.txt.length - 1);
  } else {
    this.txt = fullTxt.substring(0, this.txt.length + 1);
  }

  this.el.innerHTML = '<span class="wrap">'+this.txt+'</span>';

  var that = this;
  var delta = 300 - Math.random() * 100;

  if (this.isDeleting) { delta /= 2; }

  if (!this.isDeleting && this.txt === fullTxt) {
    delta = this.period;
    this.isDeleting = true;
  } else if (this.isDeleting && this.txt === '') {
    this.isDeleting = false;
    this.loopNum++;
    delta = 500;
  }

  setTimeout(function() {
    that.tick();
  }, delta);
};

window.onload = function() {
  var elements = document.getElementsByClassName('txt-rotate');
  for (var i=0; i<elements.length; i++) {
    var toRotate = elements[i].getAttribute('data-rotate');
    var period = elements[i].getAttribute('data-period');
    if (toRotate) {
      new TxtRotate(elements[i], JSON.parse(toRotate), period);
    }
  }
  // INJECT CSS
  var css = document.createElement("style");
  css.type = "text/css";
  css.innerHTML = ".txt-rotate > .wrap { border-right: 0.08em solid #fff }";
  document.body.appendChild(css);
};
</script>

Do you have any suggestions on how I can make this happen?

Answer №1

Utilize this code snippet:

TextRotator.rotateText = function() {
  //Avoid using modulo as it can cause an unwanted loop. If there is no full text, exit the loop without further action.
  var text = this.textArray[this.currentIndex];
  if(text) {
    if (this.isErasing) {
      this.currentText = text.substring(0, this.currentText.length - 1);
    } else {
      this.currentText = text.substring(0, this.currentText.length + 1);
    }

    this.element.innerHTML = '<span class="wrap">'+this.currentText+'</span>';

    var self = this;
    var waitTime = 300 - Math.random() * 100;

    if (this.isErasing) { waitTime /= 2; }

    if (!this.isErasing && this.currentText === text) {
      // If this is the last item in the textArray, stop the rotation before erasing.
      if(this.currentIndex >= this.textArray.length-1) {
        return;
      }
      waitTime = this.transitionDuration;
      this.isErasing = true;
    } else if (this.isErasing && this.currentText === '') {
      this.isErasing = false;
      this.currentIndex++;
      waitTime = 500;
    }

    setTimeout(function() {
      self.rotateText();
    }, waitTime);
  }
};

Good luck with your coding endeavors!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Enhancing React Native experience by dynamically editing array elements

This code block defines the state of my program, including an array: this.state = { arr: [{ arrid: 0, arrEmail: '', arrName: '', arrPhone: '' }], id: 0, email: "", isChecked: true, name: "", phon ...

Retrieve information from Django and pass it to the Vue template

I'm attempting to transfer information from Django into Vue template variables. views.py def index(request): myvar = 1 return render(request, 'index.html',{'myvar':myvar}) within index.html <span> {{ myvar }} </span& ...

The contents of Ionic views are not stored in a cache, so the controller must

In my ionic application, I have several views. When I launch the app, it takes me to the main view where data is loaded upon initialization of the controller. The issue arises when I navigate away from this view using tabs; sometimes the controller gets d ...

Exploring the intricacies of multidimensional array scopes in AngularJS

I have a JSON value that includes a list of countries and states. I want to split this value into two different scopes: $scope.countries and $scope.states. When the country is changed, the state should change based on the selected country. Sample JSON da ...

Different width can be set for the Google Maps template specifically for mobile mode by following these steps

Is there a way to adjust the width of a Google Maps template specifically for mobile mode? While it looks perfect on desktop, the map overflows the screen size on mobile. See my code snippet below: @section ('map') <div id="map"></d ...

What causes the width of unrelated cells to change when the contents of colspan'd cells expand in IE7?

Before we delve into the details, I invite you to take a look at this fiddle using IE7. It's quite intricate and not something I want to repeat here. The main issue is that clicking on the red block should display additional information. The top row ...

Guide to fetching external data with Next.js and importing the component into a different file

I have implemented the following code in my pages/github file, and when I navigate to localhost:3000/github, the code runs successfully and returns JSON data. function GithubAPI(props) { // Display posts... return (<div>{props.data.name}</div& ...

Put a watch on a variable as soon as it is set

When initializing a variable, I want to use the $watch function in Angular without it automatically initializing right away. Is there a way to accomplish this? $watch $scope.$watch(function () { return $scope.character.level; }, function (ne ...

The child's styling is conflicting with the parent's styling

Issue with Parent and Child Component Margins import "../src/App.css"; import CardComponent from "./components/CardComponent"; function App() { return ( <div className="App"> <div className="card"></div> <CardCompon ...

Implementing hashing with resumable.js

Looking for a way to include hashing in resumable.JS by utilizing the "fileAdded" event hook. Any suggestions on how to add hash to each chunk? ...

Chrome extensions using Cross-Origin XMLHttpRequest

Chrome extensions API states that cross-origin calls using the XMLHttpRequest object should be allowed with proper permissions: An extension can communicate with remote servers beyond its origin by requesting cross-origin permissions. Following the Goog ...

Multiple 'keydown' events are accumulating with Ajax activated

When the search field is focused, I am loading JSON into the browser and then iterating over the JSON objects to find real-time results 'on keydown'. The issue I'm encountering is detailed in the console after the initial block of code Aja ...

Set iframe scroll to match the height of the user's screen resolution

Can the height of an iframe scroll be adjusted to match the size of the screen (browser)? Essentially replacing the default browser scroll with the iframe scroll. Here's what I'm looking to achieve: Currently, my browser scroll is disabled: < ...

Customizing the Image Insert Dialog in Pagedown Editor

I've developed a custom insertImageDialog hook to enable file uploads directly within the editor. $('div#insertImageDialog input[type=file]').ajaxfileupload({ action: $file.attr('data-action'), ...

The height on iPad Chrome is displaying incorrectly

iPad Pro(11-inch), iPadOS version: 16.6.1, Chrome version: 116.0.5845.177 I tried running a simple html file on my iPad and encountered an issue. Despite setting the height to 100vh, a vertical scrollbar appeared on the right side of the screen allowing ...

What causes the CSS `resize` property to be inherited in Chrome browsers?

It was my understanding that elements do not inherit the resize property from their parent elements. However, I recently discovered that in Chromium they actually do: Here is a screenshot of Chromium's inspector: Check out this demo: http://jsfi ...

Move the width from left to right with animation

Currently, I am exploring ways to use jQuery to create an animation effect on a div where the width shrinks from left to right. My first step is to have the element animate as follows: Slide in from left to right Then continue moving to the right off th ...

Updating website content dynamically using AJAX and URL manipulation without refreshing the page (Node.js)

How can I update the inventory without refreshing the page using both button events and URLs? I want to be able to update to a specific page based on the URL parameter (like /inventory/2) when it is passed to the route. Currently, my AJAX request works but ...

Could this truly be jQuery in action?

Once more, here is some code snippet: audioElement.addEventListener('ended', function() { $('span#pause').fadeOut('slow'); $('span#play').delay(1500).fadeIn('slow'); }); I believe that "addEventLi ...

Stop the submission of MVC Form

Using AJAX, I have a form with fields in a partial view that is sent to a controller action when submitted. The partial view appears in a pop-up div when a button on the main form is clicked. If the user completes and submits the form, the update is succes ...