Unable replace characters from one string to another - Is it a Javascript bug?

Viewed 64

I'm trying to make an effect of replacing one string with another, but without completely erasing the contents of the first one. As if it were a special effect, each letter of a string is transformed into another word. At first I'm trying to do it like a typewriter, but later I want to do it randomly. However, I can't get it to work, it looks like it's a bug.

let title1 = "Your sales place";
let title2 = "Software Hub";

var k = 0;
var speed = 150;

function typeWriter() {
  if (k < title1.length) {
    if (k >= title2.length) {
      title2 += title1.charAt(k);
    }
    title2 = title2.replace(title2.charAt(k), title1.charAt(k));
    document.getElementById("demo").innerHTML = title2;
    k += 1;
    setTimeout(typeWriter, speed);
  }
}

typeWriter();
<div id="demo"></div>

output:

YO AESRL SUPLACE
3 Answers

replace replaces the first occurrence of the character, which is not necessarily the one at index k.

Instead of mutating title2, I would recommend to simply do

….innerHTML = title2.slice(0, k) + title1.slice(k);

This is the correct code for what i'm waiting. Sorry for the mistake.

import { onMount } from "svelte";

    let title1 = "Your sales place";
    let title2 = "Software Hub";
    var part = "";
    var k = 0;
    var speed = 150;

    onMount(() => {
        typeWriter();
    });

    function sliceReplace(origin, final, k) {

        part = part.slice(0,k);
        part += final.charAt(k) + origin.slice(k+1);
        return part;

    }

    function typeWriter() {
        if (k < title1.length) {
            if (k >= title2.length) {
                title2 += title1.charAt(k);
            }
            document.getElementById("demo").innerHTML = sliceReplace(title2, title1, k);
            k += 1;
            setTimeout(typeWriter, speed);
        }
    }

This is your solution with the least modification. The problem with your code is using String.prototype.charAt to find and replace your character, and it finds the first occurrence of a character. So when a character is repeated in your string, charAt will find and replace the first occurrence, not the other ones.

So you can define a function like replaceAt below, to replace a character at a specific position, and use that.

let title1 = "Your sales place";
let title2 = "Software Hub";

String.prototype.replaceAt = function(index, replacement) {
    return this.substr(0, index) + replacement + this.substr(index +   replacement.length);
}

var k = 0;
var speed = 150;

function typeWriter() {
  if (k < title1.length) {
    if (k >= title2.length) {
      title2 += title1[k];
    } else {
      title2 = title2.replaceAt(k, title1[k]);
    }
    document.getElementById("demo").innerHTML = title2;
    k += 1;
    setTimeout(typeWriter, speed);
  }
}

typeWriter();
<div id="demo"></div>

However, I would recommend that you do not use global variables as counters when recursively calling a function, instead, pass that variable to your function:

let title1 = "Your sales place";
let title2 = "Software Hub";

var speed = 150;

String.prototype.replaceAt = function(index, replacement) {
    return this.substr(0, index) + replacement + this.substr(index + replacement.length);
}

function typeWriter(k) {
  if (k < title1.length) {
    let title = document.getElementById("demo").innerHTML
    if (k >= title.length) {
      title += title1[k];
    } else {
      title = title.replaceAt(k, title1[k]);
    }
    document.getElementById("demo").innerHTML = title;
    setTimeout(() => {typeWriter(k+1)}, speed);
  }
}

document.getElementById("demo").innerHTML = title2;
setTimeout(() => {typeWriter(0);}, speed)
<div id="demo"></div>

Related