2017-11-16 2 views
1

Ich habe eine einfache JavaScript/jQuery Schreibmaschine mit Backspacing geschrieben, die mehrere Nachrichten (& ein Hintergrundbild) durchschleift.Javascript Schreibmaschine schreibt nicht und Backspace richtig

Das Problem, mit dem ich konfrontiert bin, ist, dass als die Funktionen Schleife, sie nicht richtig ausgeschrieben werden - einige der Zeichen fehlen.

d. H. Mein Array ist [jeder, Hundebesitzer, die Diät-bewusste, Arbeiter, Familien] aber was wird wiederum geschrieben werden: Ryone, g Besitzer, Diät-bewusst, (leer), Familien.

Ich denke, das Problem könnte sein, dass eine Variable irgendwo nicht richtig zurückgesetzt wird oder die Länge aus der vorherigen Nachricht ausgearbeitet wird - mögliche Probleme mit dem Bereich.

Auf Codepen: https://codepen.io/nathankeenmelb/pen/MOovXJ?editors=0010

Die entsprechende HTML

<body> 
    <div> 
    <h2>There's something for<span id="message"> everyone.</span></h2> 
    </div> 
</body> 

Die JS, mit jQuery

let messages = [ 
    " everyone.", 
    " dog owners.", 
    " the diet-conscious.", 
    " workers.", 
    " families." 
]; 
let images = [ 
    "url(https://via.placeholder.com/200x100)", 
    "url(https://via.placeholder.com/400x100)", 
    "url(https://via.placeholder.com/400x200)", 
    "url(https://via.placeholder.com/400x300)", 
    "url(https://via.placeholder.com/400x400)" 
]; 

let loopDuration = 3000; 

function displayImages(arr){ 
    //Loop through other images, but start at second item 
    let j = 1; 
    setInterval(//evaluates every x ms 
     function(){ 
      $('body').css("background-image",arr[j]); 
      j++; 
      console.log('j in image = ' + j); 
      //Reset loop after been through them all to repeat 
      if(j >= images.length) j = 0; 
      //Interval length in ms 
     }, loopDuration); 
} 

function displayMessages() { 

    //CHANGE THE MESSAGE -starting the loop 
    let i = 0; 
    setInterval(//evaluates every x ms 
     function(){ 
      //TYPEWRITE MESSAGE 
      let char = 0; 
      function typeWriter() { 
       //for as long as the current character length is less than the full character length 

       if (char < messages[i].length) { 
       //Add the next character to the html 
       document.getElementById("message").innerHTML += messages[i].charAt(char); 

       //Go to next character 
       char++; 
       //Wait x ms to write next character 
       setTimeout(typeWriter, 50); 
       } 

      } //end typewriter() 

      //Run the function 
      typeWriter(); 

      //START BACKSPACE 
      let theMessage = document.getElementById("message").innerHTML; 
      let bchar = theMessage.length; 

      function backSpacer() { 
      if (bchar > 0) { 
       theMessage = theMessage.slice(0,-1); 
       document.getElementById("message").innerHTML = theMessage; 
       bchar--; 
       //Run the function again, after x m 
       setTimeout(backSpacer, 25); 
      } 
      } 
      //Run the function 
      backSpacer(); 

      //If instead of using backspacer() I deleted the text as follows, that worked fine 
      //$('#message').text(''); 
      //document.getElementById("message").innerHTML = ""; 


      //Having typed it all out, backspaced it, go to the next message 
      i++; 

      //Having gone through each message, reset loop to repeat, to 0 to include the original 
      if(i >= messages.length) i = 0; 
      //Interval length in ms 
     }, loopDuration); 

} 

//Wait till the whole page loads 
window.onload = function loadChanges() { 
    setTimeout(function() { 
    //Run whatever after time elapses 
    displayImages(images); 
    displayMessages(); 
    //Wait x ms after page loads 
    }, 1000) 
}; 
+2

Fehlersuche pro Tipp # 1: Vereinfachen. Dies ist ein großer, schwieriger Code zum Navigieren. Zerlege es in den kleinsten möglichen Teil, arbeite es, teste es, bring es zum Laufen (oder finde heraus, was damit nicht stimmt), dann baue darauf auf. Der Versuch, etwas mit so viel Code, Rekursion und Timeouts auf einmal anzugehen - das ist mehr Arbeit als nötig. –

Antwort

0

ich Ihren Code sah ein wenig. Es scheint mir, als ob Sie beide typeWriter und backSpacer zur gleichen Zeit ausgeführt haben.

Der Code hatte diese Struktur (I vereinfacht habe es viel):

setInterval(function(){ 
    function typeWriter() { 
    if (char < messages[i].length) { 
     char++; 
     setTimeout(typeWriter, 50); 
    } 

    } 

    typeWriter(); 

    let bchar = theMessage.length; 

    function backSpacer() { 
    if (bchar > 0) { 
     bchar--; 
     setTimeout(backSpacer, 25); 
    } 
    } 

    backSpacer(); 
}, loopDuration); 

Wie Sie können Sie sowohl Schreibmaschinen und Backspacer sehen nennen. Das setTimeout führt dazu, dass diese Methoden "parallel" ausgeführt werden und daher gleichzeitig Buchstaben entfernen und hinzufügen, wodurch die Nachricht durcheinander gerät.

Ich erstellte ein Arbeitsbeispiel, das eher eine Zustandsmaschine ist. Das bedeutet, dass es zuerst die Nachricht eingibt. Wenn dies geschehen ist, wird auf das Löschen der Nachricht umgeschaltet. Und wenn das erledigt ist, wartet es auf einen Neustart.

Der Code ist nicht großartig, aber es funktioniert irgendwie und könnte Ihnen helfen, zu einer funktionierenden Lösung zu kommen. Lassen Sie mich in den Kommentaren wissen, wenn Sie irgendwelche Fragen haben.

https://codepen.io/andreasmcdermott/pen/ZaXXyK?editors=0010

+0

Danke, Sie haben das Problem gelöst und einen besseren Weg gefunden, den richtigen Zeitpunkt zu finden. Ich denke, ich kann die Logik Ihrer Lösung sehen, also werde ich das die Lösung nennen. – Nathan