试图逐个附加文本

时间:2013-09-26 14:17:07

标签: javascript jquery settimeout

嗨,我是JavaScript和Jquery的新手。我在这里尝试做的是使用setTimeout函数打印onclick()函数字母表中传递的文本。我不确定我做错了什么。谢谢你的帮助。

HTML

<div>
         <p id='myTxt'></p>
</div>
 <input type='button' value='Submit' onclick="imScrolling('Hello World!!', 500, 0, document.getElementById('myTxt'))">   

我的Script.js文件

 function imScrolling(scrollTxt, interval, index, target)
    {
        //alert(scrollTxt + " " + interval + " " + scrollTxt.length + " " + index + " " + target.id);
       while(index < scrollTxt.length)
      {
         //alert(scrollTxt[index]);
         setTimeout(function (scrollTxt, interval, index, target)
                {
                   $('#myTxt').append(scrollTxt[index]);
                   }, interval);
         index++;       
       }
    }

另外,我注意到如果我没有将参数传递给setTimeout(),那么index,interval等参数在警告消息中显示为undefined?为什么会这样?

5 个答案:

答案 0 :(得分:1)

问题是setTimeout是异步的,但您的函数会同步运行while,因此setTimeout会立即多次设置。这就是我的建议:

function imScrolling(scrollTxt, interval, index, target)
{
   setTimeout(function (){
       $('#myTxt').append(scrollTxt[index]);
       if(index < scrollTxt.length){
        imScrolling(scrollTxt, interval, index+1, target);
       }
       }, interval);
}

这样,您将在第一个触发后再次设置间隔而不是“同时”。 Demo

答案 1 :(得分:0)

尽量不要在HTML上使用事件属性。

jQuery可以帮助你。

尝试:

HTML

<div id="container">
    <p id="myTxt"></p>
    <input type="button" value="Submit" id="your-button" /> 
</div>

JAVASCRIPT

$(function () // jquery dom ready
{
    $("#container")
        .on("click", "#your-button", function ()
        {
            var yourText = "Hello World!!".split('');

            for (var i = 0; i < yourText.length; i++)
            {
                $("#myTxt")
                    .append(yourText[i])
                    .append("<br/>"); // just to line break
            }
        }
});

工作fiddle

答案 2 :(得分:0)

首先让我们开始使用setTimeout调用的函数。

function (scrollTxt, interval, index, target) {
  $('#myTxt').append(scrollTxt[index]);
}

您已经定义了一个具有4个参数的函数,以后再调用它们。问题是给setTimeout的函数在被调用时没有传递任何参数,因此在匿名函数scrollTxt中,interval,index和target将是未定义的。

要解决此问题,您可以使用闭包。在匿名函数中,您可以使用范围中可用的变量来定义匿名函数:

 var a = 5;
 function () {
    console.log(a); // 5
 }

还有一个问题。使用的变量是实际变量,而不是副本。因此,如果您将变量更改为外部,匿名函数内的值也将更改:

var a = 5;
var f = function () {
  console.log(a);
}
a = 10;
f(); // outputs 10

为您更改的变量是索引。要克服这个问题,您需要为每次迭代创建一个副本。有什么比将它作为参数赋予函数更好的方法呢?

for (var i=0; i<10; i++) {
  setTimeout((function(new_i) {
     return function () {
       console.log(new_i);
     };
  })(i),100);
}
// outputs 0,1,2,3,4,5,6,7,8,9

应用此功能,您可以轻松解决问题(并了解您的解决方法)。

答案 3 :(得分:0)

请勿使用setTimeout。你想要的是setInterval

function imScrolling(scrollTxt, interval, index, target) {
    //alert(scrollTxt + " " + interval + " " + scrollTxt.length + " " + index + " " + target.id);

    var notawhileloop = setInterval(function () {
        //alert(scrollTxt[index]);
        $('#myTxt').append(scrollTxt[index]);
        index++;
        if (index == scrollTxt.length) {
            clearInterval(notawhileloop);
        }
    }, interval);
}

Working jsfiddle with your HTML

编辑:哎呀,忘了停止循环播放。更新了小提琴。


编辑2:找到了a neat trick,这样也很容易使用setTimeout执行此操作。

function imScrolling(scrollTxt, delay, index, target) {
    while (index < scrollTxt.length) {
        setTimeout(appendLetter, index * delay, scrollTxt, index);
        index++;
    }
}
function appendLetter(scrollTxt, index) {
    $('#myTxt').append(scrollTxt[index]);
}

See it working in this fiddle。诀窍是将delay乘以index(因此第一次超时设置为0 * 500,第二次设置为1 * 500,第三次设置为2 * 500等)。希望这也证明了参数的传递。

答案 4 :(得分:0)

> Live demo

function imScrolling(txt, intv, i, elID){

  var $el = $(elID),
      tot = txt.length,
      interv = setInterval(doIt, intv);   

  function doIt(){
    $el.append(txt[i++]);
    if(i==tot) clearInterval(interv);
  }

}

现在有趣了:

如何使用jQuery的动画方法:

而不是setInterval,如果你想控制动画发生的总时间,你可以使用
  .animate() 并且 step 功能:

> Live demo (3500ms)

function imScrolling(txt, time, i, elID){

    $({c:i}).animate(
      {c:txt.length},{
       duration : time,
       easing : 'linear',
       step : function(now){
           d = ~~(now);
           r = ~~(this.c);
           if(d!==r)$(elID).append(txt[r]);
       }
      }
    );     

}