我有一个jsp页面,它为某些HTML元素设置'timestamp'属性。我使用这些'timestamp'的值来显示格式的时间 - “10秒前更新”(作为工具提示)
我已经创建了一个静态HTML页面来演示我的问题。 这是我的代码:
<html>
<head>
<script type = "text/javascript">
function setTime() {
var currentDate = new Date();
var elem = document.getElementsByClassName('supermaxvision_timestamp');
if(elem) {
for (var i = 0; i < elem.length; i++) {
var timestamp = elem[i].getAttribute('timestamp');
if(timestamp) {
var startTimestamp = new Date();
startTimestamp.setTime(timestamp)
var difference = currentDate.getTime() -startTimestamp.getTime();
elem[i].innerHTML = difference + " milliseconds";
}
}
}
setInterval(setTime, 1000);
}
</script>
</head>
<body>
<div class='supermaxvision_timestamp' timestamp='1353389123456' ></div>
<div class='supermaxvision_timestamp' timestamp='1353389234567' ></div>
<div class='supermaxvision_timestamp' timestamp='1353389345678' ></div>
<div class='supermaxvision_timestamp' timestamp='1353389456789' ></div>
<div class='supermaxvision_timestamp' timestamp='1353389567890' ></div>
<button onclick="setTime()">start</button>
</body>
</html>
您只需将此代码复制粘贴到文本文件中,然后在浏览器中打开(只需点击“开始”按钮一次)。
问题是我的div的值最初会每秒更新一次(代码 - setInterval(setTime, 1000)
)。但是慢慢地更新间隔减少并且值立即更新。浏览器在一分钟内停止响应。
我没有在循环中调用setInterval
。这可能有什么问题?
此外,此代码在IE中不起作用。
答案 0 :(得分:3)
setInterval(fn, ms)
表示每隔fn
毫秒运行ms
,从现在开始直到我清除此间隔。但是在每次通话时,你设置一个新的间隔,与最后一个相同。
只需将setInterval
更改为setTimeout
即可重复,只调用一次提供的功能。 setTimeout
可以通过调用递归设置新超时的函数来模拟setInterval
。如果您按间隔执行此操作,则会安排越来越多的永不停止的间隔。每次调用自己时,预定间隔的数量加倍。它很快失控了......
或者,您可以将setInterval
移出setTime
函数并仅调用一次,这将使其每秒调用一次。比如说:
// button calls this.
function startTime() {
setInterval(setTime);
}
function setTime() {
// all that code, but minus the setInterval at the end
}
答案 1 :(得分:0)
你正在递归地调用setInterval
。每次创建新间隔时,该间隔都会创建一个新间隔。最终浏览器无法处理它。
也许你会喜欢这样的东西?
<button onclick="setInterval(setTime, 1000)">start</button>
答案 2 :(得分:0)
setInterval开始一个重复函数 - 因为它现在是setTime它的循环和逻辑然后每秒调用setTimeout,每个setTimeout调用然后每秒开始另一次重复调用。如果你使用setTimeout,它只会被调用一次,但我的建议是你只需在函数声明之外运行setInterval,如:
<html>
<head>
<script type = "text/javascript">
function GEBCN(cn){
if(document.getElementsByClassName) // Returns NodeList here
return document.getElementsByClassName(cn);
cn = cn.replace(/ *$/, '');
if(document.querySelectorAll) // Returns NodeList here
return document.querySelectorAll((' ' + cn).replace(/ +/g, '.'));
cn = cn.replace(/^ */, '');
var classes = cn.split(/ +/), clength = classes.length;
var els = document.getElementsByTagName('*'), elength = els.length;
var results = [];
var i, j, match;
for(i = 0; i < elength; i++){
match = true;
for(j = clength; j--;)
if(!RegExp(' ' + classes[j] + ' ').test(' ' + els[i].className + ' '))
match = false;
if(match)
results.push(els[i]);
}
// Returns Array here
return results;
}
function setTime() {
var currentDate = new Date();
var elem = GEBCN('supermaxvision_timestamp');
if(elem) {
for (var i = 0; i < elem.length; i++) {
var timestamp = elem[i].getAttribute('timestamp');
if(timestamp) {
var startTimestamp = new Date();
startTimestamp.setTime(timestamp)
var difference = currentDate.getTime() -startTimestamp.getTime();
elem[i].innerHTML = difference + " milliseconds";
}
}
}
}
</script>
</head>
<body>
<div class='supermaxvision_timestamp' timestamp='1353389123456' ></div>
<div class='supermaxvision_timestamp' timestamp='1353389234567' ></div>
<div class='supermaxvision_timestamp' timestamp='1353389345678' ></div>
<div class='supermaxvision_timestamp' timestamp='1353389456789' ></div>
<div class='supermaxvision_timestamp' timestamp='1353389567890' ></div>
<button onclick="setInterval(setTime, 1000)">start</button>
</body>
</html>
此外,这在IE中不起作用的原因是它不能正确支持文档的getElementsByClassName方法。我发现在这里:IE 8: Object doesn't support property or method 'getElementsByClassName'和Rob W也在那里给出了一个很好的解释,但是为了快速回答我已经使用querySelectorAll
修改了上面的代码以便在IE中工作好的,我刚才说没有意义,但我已经复制了所有的代码,上面是一个工作,测试(在ie和ff)你想要的例子