Frage

    

Diese Frage bereits eine Antwort hier:

         

Ich möchte eine Zeichenfolge-für-Zeichen angezeigt werden mit dem folgenden Code:

function initText()
{
    var textScroller = document.getElementById('textScroller');
    var text = 'Hello how are you?';

    for(c = 0; c < text.length; c++)
    {
        setTimeout('textScroller.innerHTML += text[c]', 1000);
    }
}

window.onload = initText;

Es funktioniert nicht .. was mache ich falsch?

War es hilfreich?

Lösung

Versuchen Sie etwas wie folgt aus:

function initText()
{
    var textScroller = document.getElementById('textScroller');
    var text = 'Hello how are you?';

    var c = 0;
    var interval = setInterval(function() { 
                          textScroller.innerHTML += text[c]; 
                          c++; 
                          if(c >= text.length) clearInterval(interval);
                   }, 1000);

}

Hinweis I clearInterval hinzugefügt, um es zu stoppen, wenn sie gebraucht wird.

Andere Tipps

Derzeit Sie definieren 18 Timeouts und alle ~ auf einmal ausgeführt werden. Zweites Problem ist, passieren Sie Anweisungen als String auszuführen. In diesem Fall muß der Code nicht Zugriff auf alle Variablen in initText definiert, weil wertete Code in globalem Bereich ausgeführt wird.

IMO, sollte dies den Job

function initText(){
    var textScroller = document.getElementById('textScroller');
    var text = 'Hello how are you?';

    var c = 0;

    (function(){
        textScroller.innerHTML += text.charAt(c++);
        if(text.length > c){
            setTimeout(arguments.callee, 1000);
        }
    })();
}

Noch mehr Generika als Antwort von @ Yauhen-Yakimovich:

Mit Timeout:

var repeat = (function () {
    return function repeat(cbWhileNotTrue, period) {
        /// <summary>Continuously repeats callback after a period has passed, until the callback triggers a stop by returning true.  Note each repetition only fires after the callback has completed.  Identifier returned is an object, prematurely stop like `timer = repeat(...); clearTimeout(timer.t);`</summary>

        var timer = {}, fn = function () {
            if (true === cbWhileNotTrue()) {
                return clearTimeout(timer.t); // no more repeat
            }
            timer.t = setTimeout(fn, period || 1000);
        };
        fn(); // engage
        return timer; // and expose stopper object
    };
})();

Mit Interval:

var loop = (function () {
    return function loop(cbWhileNotTrue, period) {
        /// <summary>Continuously performs a callback once every period, until the callback triggers a stop by returning true.  Note that regardless of how long the callback takes, it will be triggered once per period.</summary>

        var timer = setInterval(function () {
            if (true === cbWhileNotTrue()) clearInterval(timer);
        }, period || 1000);
        return timer; // expose stopper
    };
})();

geringfügiger Unterschied zwischen den beiden in den Kommentaren angegeben - die repeat Methode wiederholt erst nach den Rückruf führt, wenn Sie also eine „langsame“ Rückruf haben es nicht alle delay ms laufen, aber wiederholt nach jedem delay zwischen Ausführungen, während die loop Methode wird der Rückruf alle delay ms ausgelöst. Um vorzeitig stoppen, verwendet repeat ein Objekt als zurück Kennung, so Verwendung clearTimeout(timer.t) statt.

Verbrauch:

Wie Antwort von @ soufiane-Hassou:

var textScroller = document.getElementById('textScroller');
var text = 'Hello how are you?';

var c = 0;
var interval = repeat/* or loop */(function() { 
                      textScroller.innerHTML += text[c]; 
                      c++; 
                      return (c >= text.length);
               }, 1000);

Wie bereits erwähnt, würde eine vorzeitige Einstellung sein:

/* if repeat */ clearTimeout(interval.t);
/* if loop */   clearInterval(interval);

Versuchen Sie diese:

function initText()
{
    var textScroller = document.getElementById('textScroller');
    var text = 'Hello how are you?';

for(c = 0; c < text.length; c++)
{
    setTimeout("textScroller.innerHTML += '" + text[c] + "'", 1000 + c*200);
}
}

window.onload = initText;

Versuchen Sie, einen Verschluss mit:

function init() {
    var textScroller = document.getElementById('textScroller');
    var text = 'Hello how are you?';
    var c = 0;
    function run() {
        textScroller.innerHTML += text[c++];
        if (c<text.length)
            setTimeout(run, 1000);
    }
    setTimeout(run, 1000);
}
init()

Das Problem in Ihrem Code ist, dass der Code, den Sie in der Zeichenfolge setzen im globalen Kontext ausgeführt wird, wo textScroller nicht definiert ist (es innerhalb Ihrer Funktion definiert ist).

Ich möchte ein Snippet teilen (basierend auf Antwort von Soufiane Hassou). Es erstreckt sich auf den Fall, wenn man buchstäblich ein for-Schleife ersetzt Körper über einige Array in einem festen Zeitintervall wiederholt werden. Grundsätzlich gleiche Synchronschleife aber mit „Schlaf“ Pause (weil Javascript nicht eine synchrone Programmiersprache ist).

function loop(arr, take, period) {
    period = period || 1000;
    var i = 0;
    var interval = setInterval(function() { 
        take(i, arr[i]);
        if (++i >= arr.length) { clearInterval(interval);}
    }, period);
}

Anwendungsbeispiel:

loop([1, 2, 3, 4], function(index, elem){
    console.log('arr[' + index + ']: ' + elem);
});

Getestet in Knoten JS. Hoffnung, dass jemand hilft.

Bearbeiten>

Das folgende Update macht Code verwendbar zusammen mit Libs tun schweren "Prototyping" (wie jQuery oder Prototyp):

function loop(arr, take, period) {
    period = period || 1000;
    var scope = {
        i: 0,
        arr: arr,
        take: take,
    };
    var iterate = (function iterate() {
        if (this.i >= this.arr.length) { clearInterval(this.interval); return}
        take(this.i, this.arr[this.i++]);
    }).bind(scope);
    scope.interval = setInterval(iterate, period);
}

Ihr for-Schleife wird sofort ein Timeout für jedes Zeichen einstellen, so dass sie nicht in der Reihenfolge angezeigt, aber auf einmal. Ihre SetTimeout sollte Code zu einem anderen SetTimeout enthalten, die das nächste Zeichen Anzeige enthalten wird.

So etwas wie diese (hätte das nicht getestet)

function initText()
{
    var textScroller = document.getElementById('textScroller');
    var text = 'Hello how are you?';    
    setTimeout('nextChar(text)', 1000);
}
function nextChar(text){
    if(text.length > 0){
        textScroller.innerHTML += text[0]; 
        setTimeout('nextChar(text.substring(1))', 1000);
    }
}

Wenn Sie setTimeOut (anstelle von setInterval) und verwenden benannte Funktion (anstelle des Auswertens Codeblock in setTimeOut Anruf) erhalten wollen, dann könnte dies hilfreich sein:

var b = {
  textScroller: document.getElementById('textScroller'),
  text: "Hello how are you?"
};


function initText() {
  for(c = 0; c < b.text.length; c++) {
    setTimeout("append("+c+")", 1000 + c*200);
  }
}

function append(c) {
  b.textScroller.innerHTML += b.text[c];
}

window.onload = initText;

Mit dem oben Ihnen einen Parameter Append-Funktion übergeben kann.

Um mehrere Parameter den nächsten Code funktioniert der Trick übergeben:

var glo = [];

function initText()
{
  var textScroller = document.getElementById('textScroller');
  var text = "Hello how are you?";
  var timeout_time;
  for(c = 0; c < text.length; c++) {
    glo[glo.length] = {text:text, c:c, textScroller:textScroller};
    timeout_time = 1000 + c * 200;
    setTimeout("append(" + (glo.length - 1) + ")", timeout_time);
  }
}

function append(i)
{
  var obj = glo[i];
  obj.textScroller.innerHTML += obj.text[obj.c];
  obj = null;
  glo[i] = null;
}

window.onload = initText;

Mit der oben Sie haben nur ein globales Array glo. In Schleife erstellen Sie neue Array Mitglieder glo und in append() Funktion dieser Elemente verweisen mit Index, der als Parameter übergeben wird.

ACHTUNG: das zweite Codebeispiel ist nicht dazu gedacht, so gut oder am besten geeignete Lösung für OP: s Problem, aber in anderen setTimeOut relativen Problemen profitieren kann, zum Beispiel. wenn jemand will, eine Präsentation oder Performance-Test, wo einige Funktionalitäten machen nötig sind, um nach einer gewissen Verzögerung zu nennen. Der Vorteil dieses Code ist die Verwendung von für Schleifen (viele Programmierer verwenden mögen für Schleifen) und die Möglichkeit, zu verwenden, auch innere Schleifen und die Fähigkeit, „send“ lokaler Variablen in ihrem Loopzeit Zustand timeOut Funktionen zu machen.

kann besser sein, in Kaskade Schleife. Für exemple ein div verblassen:

div=document.createElement('div');
div.style.opacity=1;
setTimeout(function(){fade(1);},3000);
function fade(op){
    op-=.05;
    if(op>0) setTimeout(function(){div.style.opacity=op;fade(op);},30);
    else document.body.removeChild(div);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top