CiucaS
CiucaS

Reputation: 2128

Shift one char from string every second

for learning purpose i'm trying to move an <p> tag innerHTML by one char every second. I managed to move it, but i can't set that delay between moves. It just moves it instantly.

function shiftAChar(str) {
    charToShift = str[str.length - 1];
    return charToShift + "" + str.substring(0, str.length - 1);
    console.log(str);
    setTimeout(shiftAChar, 1000);
}

function shiftString(str) {
    for (i = 0; i <= 40; i++) {
        console.log(str);
        str = shiftAChar(str);
        document.getElementById("divSecundar").getElementsByTagName("p")[0].innerHTML = str;
    }
}




window.onload = function () {
    document.getElementById("runEffect").addEventListener("click", function () {
        str = document.getElementById("divSecundar").getElementsByTagName("p")[0].innerHTML;
        console.log(str);
        shiftString(str);
    });
    document.getElementById("stopEffect").addEventListener("click", function () { run = false; })
}

HTML :

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Nu are</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
    <script type="text/javascript" src="evenimente.js"></script>


</head>
<body>
    <h2>Header Two</h2>
    <div>
        <div id="divSecundar">
            <p>Aceasta este primul paragraf</p>
            <p>Aceasta este al treilea</p>
        </div>
        <p>Aceasta este cel de-al doilea paragraf</p>
    </div>
    <input type="text" value="asdf" id="textBoxInput" />
    <input type="button" value="Run effect" id="runEffect" />
    <input type="button" value="Stop effect" id="stopEffect" />
    <input type="button" value="Animatie" id="animatie" />
    <br />
    <br />
    <input type="button" value="Click" id="btnClick" />
    <input type="button" value="Click" id="btnClickRemove" />

</body>
</html>

I don't want to use jQuery. Can it be achived using only pure javascript code?

My solution :

function shiftAChar(str) {
    charToShift = str[str.length - 1];
    return charToShift + "" + str.substring(0, str.length - 1);
}

function shiftString(str, counter) {
    if (counter <= 5) {
        str = shiftAChar(str);
        document.getElementById("divSecundar").getElementsByTagName("p")[0].innerHTML = str;
        setTimeout(function () {
            shiftString(str, ++counter);
        }, 1000);
    }
}




window.onload = function () {
    document.getElementById("runEffect").addEventListener("click", function () {
        str = document.getElementById("divSecundar").getElementsByTagName("p")[0].innerHTML;
        console.log(str);
        shiftString(str, 0);
    });
}

Upvotes: 0

Views: 149

Answers (1)

David
David

Reputation: 218877

I think you're close. Specifically you don't want to do this in a loop per se, but instead you'd pseudo-recursively call the function using setTimeout (as you're attempting). I think the problem you're finding is that the loop and the setTimeout attempt are both trying to do the same thing, and the loop is simply doing it faster.

For the sake of simplicity, let's assume the logic to move a character from one element to the other is encapsulated in the function moveOneCharacter(). (This would include the actual UI updating.) Since you already know how to make that work, this answer can just focus on the timing problem.

Structurally, the overall process might look something like this:

function shiftTheNextCharacter() {
    moveOneCharacter();
    if (charactersRemain()) {
        setTimeout(shiftTheNextCharacter, 1000);
    }
}

No loop needed. Once you call this shiftTheNextCharacter() function, it will move the first character. If there are any more characters (you'd have to write that function too, of course), it schedules itself to shift the next one.

This assumes there's always at least one character to start, of course. You can modify the logic accordingly. But the point of the structure is that a loop will do things instantly, whereas scheduling operations to happen at a later time gives you control over that timing.

Upvotes: 2

Related Questions