我正在使用以下代码在 90 秒后滑动一组 DIV。最初,滑动效果很好,但几个小时后,滑动统计数据发生得更加随机。
function loadTemplateDisplayInterval()
{
var timeload=90000;//slide will change after 1.5 mints
var count = <s:property value="#request.templates.size()" />;
var timeOut=setTimeout(function() {
var prev=display_div;
display_div++;
if($("#container_" + prev).is(":visible"))
{
$("#container_" + prev).hide(100).removeClass("fadeInLeftBig").addClass("fadeOutRightBig");
$("#container_"+display_div).show(100).removeClass("fadeOutRightBig").addClass("fadeInLeftBig");
}
if(display_div>count)
{
display_div=1;
prev=count;
$("#container_" + prev).hide(100).removeClass("fadeInLeftBig").addClass("fadeOutRightBig");
$("#container_"+display_div).show(100).removeClass("fadeOutRightBig").addClass("fadeInLeftBig");
setTimeout(function() {
loadTemplateDisplayInterval();
},timeload);
}
else
{
loadTemplateDisplayInterval();
}
clearTimeout(timeOut);
}, timeload);
}
Div 的结构为,
<div class="container-fluid animated" id="container_1"
style="opacity: 0.01">
<div class="row">
row 1
</div>
</div>
<div class="container-fluid animated" id="container_2"
style="opacity: 0.01">
<div class="row">
row 1
</div>
</div>
<div class="container-fluid animated" id="container_3"
style="opacity: 0.01">
<div class="row">
row 1
</div>
</div>
我无法思考,这可能会发生。我们唯一注意到的是,当我们没有 d3.js 组件时,这个问题就不会发生。
编辑:使用 d3.js 代码更新
var font_size = new Array();
var all_topics = new Array();
$('#' + divid).css('height', graph_h + "px").css("width", row_6 + "px");
$.post('<s:url value="/advance/topicsWarroomElement" />', {
setting_id : setting_id
}, function(data) {
var vals = eval('(' + data + ')');
if (vals.length > 15) {
//var temp = vals.length - 12;
vals = vals.slice(0,12);
}
for ( var i = 0; i < vals.length; i++) {
var x = vals[i];
var temp_font = getFont(x.weight, i);
all_topics.push({
"Text" : x.text,
"Size" : temp_font,
});
font_size.push(temp_font);
}
//console.log(all_topics);
var fill = d3.scale.category20();
d3.layout.cloud().size([ row_6, graph_h ]).words(
all_topics.map(function(d) {
return {
text : d.Text,
size : d.Size
};
console.log(d.Text);
}))
.padding(function(d) {
if (d.size <= 25 && vals.length <= 5) {
return 10;
} else {
return 5;
}
}).rotate(function() {
return 0;
}).fontSize(function(d) {
return d.size;
}).on("end", draw).start();
function draw(words) {
console.log(words);
var element = document.getElementById(divid);
d3.select(element).append("svg").attr("width", row_6).attr(
"height", graph_h).append("g").attr(
"transform",
function(d) {
return "translate(" + [ row_6 / 2, graph_h / 2 ]
+ ")";
}).selectAll("text").data(words).enter().append("text")
.style("font-size", function(d, i) {
return font_size[i] + "px";
}).style("font-family", " Helvetica,Arial,sans-serif")
.style("fill", function(d, i) {
return fill(i);
}).attr("text-anchor", "middle").attr(
"transform",
function(d) {
return "translate(" + [ d.x, d.y ]
+ ")rotate(" + d.rotate + ")";
}).text(function(d) {
return d.text;
});
}
if (draw !== true) {
progressbar(divid);
}
setTimeout(function() {
getTopics(setting_id, graph_type, divid, true);
}, 2 * interval * 60 * 1000);
});
font_size = [];
all_topics = [];
编辑2 在提出建议之后,很明显 setTimeout 或 setInterval 一段时间后就会变得疯狂。我添加了时间间隔检查,我的新方法如下所示。但即便如此,我还是发现时间本身并不正确,并且这种差异在很多时候都是错误的,无论如何都要解决这个问题。
function loadTemplateDisplayInterval()
{
console.log('call load template display ');
var timeload=30000;//slide will change after 1.5 mints
var count = <s:property value="#request.templates.size()" />;
var lastTrigger = new Date().getTime();
var timeOut=setInterval(function()
{
console.log('difference -->'+ (new Date().getTime() - lastTrigger));
if((new Date().getTime() - lastTrigger)>=timeload)
{
lastTrigger= new Date().getTime();
console.log('Entering timeout '+display_div);
var prev=display_div;
display_div++;
if($("#container_" + prev).is(":visible"))
{
$("#container_" + prev).hide(100).removeClass("fadeInLeftBig").addClass("fadeOutRightBig");
$("#container_"+display_div).show(100).removeClass("fadeOutRightBig").addClass("fadeInLeftBig");
}
if(display_div>count)
{
display_div=1;
prev=count;
$("#container_" + prev).hide(100).removeClass("fadeInLeftBig").addClass("fadeOutRightBig");
$("#container_"+display_div).show(100).removeClass("fadeOutRightBig").addClass("fadeInLeftBig");
console.log('call load template display if block');
//loadTemplateDisplayInterval();
}
}
}, 10000);
}
上述通话的时间记录 此时间日志显示,即使连续两次调用的日期差异也是不正确的。这怎么可能是正确的。
difference -->30058
Entering timeout 2
difference -->30053
Entering timeout 1
difference -->30052
Entering timeout 2
difference -->30058
Entering timeout 1
difference -->9999
difference -->9978
问候, 阿尤什
最佳答案
遗憾的是
setInterval
并不精确。我曾经使用 setTimeout(1000)
创建了一个时钟,结果是一场灾难 - 触发时间波动很大,甚至高达 +-30%。
因此,运行长期迭代setTimer
,在后台(浏览器最小化)的可能性可能会更多,因为浏览器倾向于为最小化的选项卡/窗口提供较低的执行优先级。
您应该做的是:将间隔减少大约 10 倍,并且每次触发时,检查自上次操作以来实际耗时。当时间在您期望的容差范围内时,触发您的代码。测量绝对运行时间非常重要,因为总结触发的超时不精确,并且每次迭代误差都会变大。
编辑:要获取自纪元以来的当前时间(以毫秒为单位),请使用new Date().getTime()
。您可以在每次触发操作时保存该值,并检查中间间隔的耗时。只需减去这些值,当接近您的间隔时间时,再次触发您的操作。
编辑 2:测量间隔时间的示例:http://jsbin.com/jerizemala/1/edit?html,js,console
关于javascript - setTimeout 几个小时后滑动速度更快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30795398/