嗨,我是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?为什么会这样?
答案 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)
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);
}
}
现在有趣了:
而不是setInterval
,如果你想控制动画发生的总时间,你可以使用
.animate()
并且 step
功能:
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]);
}
}
);
}