2016-07-11 6 views
1

Ich habe versucht, einen animierten Schreib/Lösch-Effekt zu erstellen. Es tippt, aber wenn es den ersten Satz beendet, macht es nichts anderes. Es scheint, dass es in der allerersten if-Anweisung stecken geblieben ist.Animierte Eingabe in nativem JavaScript

window.onload =() => { 
    const sentences = ['Who am I?', 'Who are you?', 'Who are we?']; 
    const input = document.getElementsByName('q')[0]; 

    let sentence = 0; 
    let character = 0; 
    let typing = true; 

    (function typing() { 

    if (character === sentences[sentence].length - 1) { 
     typing = false; 
    } else if (character === 0) { 
     if (sentence < sentences.length - 1) { 
     sentence++; 
     } else { 
     sentence = 0 
     } 
     typing = true; 
    } 

    if (typing) { 
     character++; 
    } else { 
     character--; 
    } 

    input.placeholder = sentences[sentence].substring(0, character); 

    setTimeout(typing, ~~(Math.random() * (300 - 60 + 1) + 60)); 
    })(); 

}; 
+2

Verwenden Sie unterschiedliche Namen für die Funktion und die Variable 'typing', sonst außer Kraft setzen Sie die Funktion mit' Typisierung = true | false' – webdeb

+1

Nur neugierig, warum Sie manchmal mit 'var' und manchmal "lassen"? – gcampbell

+0

Es ist ein Fehler. Ich wollte für die ersten beiden Variablen 'const' anstelle von' var' verwenden. – Jamgreen

Antwort

1

Sie außer Kraft setzen Ihre Funktion in der Funktion selbst, erhält setTimeout einen boolean als erstes Argument

Für Funktionsnamen ist es besser, Verben wie typeSentence
Für boolean seine gute Fragen zu verwenden, wie isTyping

+0

Ich bin vielleicht zu müde, um im Moment zu programmieren: D Danke – Jamgreen

0

Werfen Sie einen Blick auf diesen Ansatz mit Promises und einige Array Funktionen:

var sentences = ['Who am I?', 'Who are you?', 'Who are we?'], 
 
input = document.getElementsByName('q')[0]; 
 

 
// Waits for a time passed as parameter 
 
let wait = ms =>new Promise(resolve => setTimeout(resolve, ms)), 
 

 
isPaused, 
 

 
// Function that returns a Promise that remove ONE character from the placeholder 
 
removeOne =()=> new Promise((rs, rj) =>{ 
 
    setTimeout(()=>{ 
 
    input.placeholder = input 
 
     .placeholder 
 
     .substring(0, input.placeholder.length - 1); 
 
    rs(); 
 
    }, ~~(Math.random() * (300 - 60 + 1) + 60)); 
 
}), 
 

 
// Function that takes a char and return a Promise that add the char to placeholder 
 
addOne = char => new Promise((rs, rj) =>{ 
 
    if (isPaused) return rj('Paused'); 
 
    setTimeout(()=>{ 
 
    input.placeholder += char; 
 
    rs(); 
 
    }, ~~(Math.random() * (300 - 60 + 1) + 60)); 
 
}), 
 

 
// Cleans the placeholder char by char sequentially 
 
// as random as typed. 
 
clean =()=> Array.apply(null, { length : input.placeholder.length + 1 }) 
 
    .reduce(chain => chain.then(removeOne), Promise.resolve()), 
 
    
 
// Type one sentence into the placeholder sequentially 
 
// then wait, then clean then wait 
 
type = sent => sent.split('') 
 
    .reduce((chain, char)=> chain.then(addOne.bind(null, char)), Promise.resolve()) 
 
    .then(wait.bind(null, 1000)) 
 
    .then(clean) 
 
    .then(wait.bind(null, 500)), 
 
    //.catch(Promise.reject), 
 

 
// Execute an infine loop that type each sentence 
 
// sequentially 
 
loop =()=>{ 
 
    isPaused = false; 
 
    return sentences.reduce((chain, sent)=> chain 
 
    .then(()=> type(sent)) 
 
    .catch(Promise.reject) 
 
, Promise.resolve()) 
 
.then(loop); 
 
}, 
 

 
// Change the boolean to true, this will cause a rejection in addOne Promise 
 
// then will call clean to clean the placeholder. 
 
pause =()=> { 
 
    isPaused = true; 
 
    return clean(); 
 
}; 
 

 
// Execute the loop at first time 
 
loop(); 
 

 
// Pause the execution in 20 seconds 
 
// As this is a promise you can also listen for pause to complete 
 
// i.e. pause().then(wait.bind(null, 1000)).then(loop); 
 
setTimeout(pause, 20000);
<input type = "text" name= "q">

+0

Danke. Deines ist gut, weil es eine Weile wartet, bevor die Eingabe gelöscht wird, aber ich mag den Löscheffekt in meinem Code (den Zeichenindex verringernd). Ist es möglich, mit Versprechungen dasselbe zu tun? – Jamgreen

+0

@Jamgreen Habe gerade den anwser bearbeitet! –