函数调用自己setInterval(浏览器冻结问题)
function calling itself with setInterval (browser freezing issue)
我知道已经有类似的问题了,但是我看到的答案没有一个能解决我的问题。
我写了一个小脚本,使用两个函数逐字母打印字符串:第一个函数拼写字符串,第二个函数调用第一个函数,只要单词没有完全拼写,使用setInterval
:
function write() {
writeThis = str.substring(0, currentLetter);
div.innerHTML = writeThis;
currentLetter++;
console.log('running');
}
function start() {
setInterval(function() {
if (currentLetter > str.length) {
return false;
}
write(); //calls the writing function
}, 100);
}
start();
我需要将这两个函数合并为一个,以便通过传递字符串作为参数动态地在不同的字符串上使用它。我想做这样的事情:
function write(thisString) {
//code
return thisString;
}
var str1 = "hello world";
var str2 = "foo bar";
write(str1); write(str2);
当涉及到在write()
函数中插入setInterval
来调用自己时,我卡住了。无论我尝试什么,write()
将永远调用自己(尽管if
条件)并冻结浏览器。有可能把这两个功能合并成一个吗?
此处演示:https://jsfiddle.net/Hal_9100/b5gm8nbc/
setInterval
会一直发射,直到你调用clearInterval(intervalId)
。
对于大多数动画,在任何情况下使用setTimeout
都更容易控制,如下所示:
var div = document.getElementById('div');
var str = 'hello world.';
var currentLetter = 1;
var writeThis = str.substring(0, currentLetter);
function write() {
writeThis = str.substring(0, currentLetter);
div.innerHTML = writeThis;
currentLetter++;
console.log('running');
}
function run(){
if (currentLetter > str.length) {
return false;
}
write();
setTimeout(run, 100);
}
function start() {
setTimeout(run, 100);
}
start();
如果您真的想使用setInterval
,该函数返回您需要的intervalId,因此您可以这样做:
var intervalId = setInterval(fn, 100);
则在if语句中调用
clearInterval(intervalId);
显然,您需要确保intervalId
在两个地方都在作用域中。
** EDIT **
添加使其成为一个函数。抱歉我没听清问题的这一部分。这里的技巧是使用Function.bind()
var div = document.getElementById('div');
var str = 'hello world.';
var currentLetter = 1;
var writeThis = str.substring(0, currentLetter);
function run(text){
if (currentLetter > text.length) {
return false;
}
writeThis = text.substring(0, currentLetter);
div.innerHTML = writeThis;
currentLetter++;
console.log('running');
setTimeout(run.bind(null, text), 100);
}
run(str);
如果你想传递一切(例如div, str,当前字母),只需将它们作为参数添加到run
函数,并在再次绑定时添加它们。
如果使用setInterval()
,则必须使用clearInterval()
清除间隔。
:
var interval = setInterval(function() {
var i = 0;
if(i < x) {
...
} else {
clearInterval(interval);
}
});
总:var div = document.getElementById("myDiv");
var str = "Hello world!";
function write(str) {
var i = 0;
var len = str.length;
var interval = setInterval(function() {
if (i < len) {
div.innerHTML += str[i];
} else {
clearInterval(interval);
}
i += 1;
}, 100);
}
write(str);
<div id="myDiv"></div>
下面是使用Element.typeEffect("Hello World");
的示例原型
更新:最好使用textContent
而不是innerHTML
来将字符串写为文本而不是HTML。
:
- 如果你想使用多个div的函数,避免使用递增的数字作为全局变量
- 在使用此函数之前,您的
#div
应该为空。 - 你可以使用callback在写完后触发。
var div = document.getElementById('div');
var div2 = document.getElementById('div2');
Element.prototype.typeEffect = function(str, onfinish) {
var el = this;
var i = el.textContent || el.innerText;
i = i.length;
if (i == str.length) {
if (typeof onfinish == "function") onfinish();
return;
}
el.textContent += str[i];
setTimeout(function() {
el.typeEffect(str, onfinish);
}, 100);
}
div.typeEffect("Hello World");
//optinaly callback
div2.typeEffect("Helo Again", function() {
console.log("#div2 finished");
});
<div id="div"></div>
<hr/>
<div id="div2"></div>
如果你不喜欢原型,试试这个
function typeEffect(str,el,cb) {
var i = el.textContent || el.innerText;
i = i.length;
if (i == str.length){
if(typeof cb == "function")cb();
return;
}
el.textContent += str[i];
setTimeout(function() {
typeEffect(str,el,cb);
}, 100);
}
//usage
typeEffect("Hello World",div);
//or with callback
typeEffect("Hello World",div,function(){
console.log("finished");
});
- 在指令控制器中使用$attrs时出现问题
- 将PHP变量传递给jQuery时遇到问题
- Canvas Html5绘图应用程序,移动画布会导致重大问题
- 参数变量出现ngTable指令问题
- 剑道网格jQuery动画()问题
- 在哪里使用名为“;冻结”;
- 我的jQuery插件参数没有正确启动,遇到了问题
- Phonegap-(安卓/iphone)多个图像的图像库出现问题
- TableExport jquery插件:文件名和扩展名问题
- JavaScript Pub/Sub属性访问问题
- JavaScript异步问题
- 如何解决Yii中的页面刷新问题
- Safari(Mac OS)上的jQuery平滑滚动问题
- jqGrid树网格问题
- 使用正则表达式评估电子邮件地址时出现性能问题
- 冻结列垂直滚动问题
- 检测导致冻结等问题的错误 JS
- jQuery幻灯片和停止问题:动画元素随着鼠标的快速移动而冻结
- 使用jquery插件进行分页,当加载50k时记录导致整个系统冻结.如何解决这个问题
- 函数调用自己setInterval(浏览器冻结问题)