我制作了这个代码,使得一些视觉“瓦片”渐渐消失。 但目前我遇到了一些性能问题。
虽然大多数浏览器正在运行代码(特别是firefox),但有些像safari一段时间后会出现问题(一段时间= 15秒)。
我认为这是由于我的递归函数(名为 changeopacity 的函数在延迟时永远调用自身)?或者是吗?
但无论如何问题是这个代码对于大多数浏览器来说真的很重要。是否存在或更多如何使此代码更好地执行?有什么想法吗? (代码示例会很好)谢谢: - )
实际代码:
$(document).ready(function () {
var aniduration = 2000;
var tilesize = 40;
createtable(tilesize);
$(".tile").each(function (index, domEle) {
var randomdelay = Math.floor(Math.random() * 3000);
setTimeout(function () {
changeopacity(aniduration, domEle);
}, randomdelay);
});
$("td").click(function () {
clickanimation(this, 9);
});
$("td").mouseenter(function () {
var element = $(this).find("div");
$(element).clearQueue().stop();
$(element).animate({opacity: "0.6"}, 800);
});
$("td").css("width", tilesize + "px").css("height", tilesize + "px");
});
function createtable(tilesize) {
var winwidth = $(window).width();
var winheight = $(window).height();
var horztiles = winwidth / tilesize;
var verttiles = winheight / tilesize;
for (var y = 0; y < verttiles; y++)
{
var id = "y" + y;
$("#tbl").append("<tr id='" + id + "'></tr>");
for (var x = 0; x < horztiles; x++)
{
$("#" + id).append("<td><div class='tile' style='opacity: 0; width: " + tilesize + "px; height: " + tilesize + "px;'></div></td>");
}
}
}
function changeopacity(duration, element){
var randomnum = Math.floor(Math.random() * 13);
var randomopacity = Math.floor(Math.random() * 7);
var randomdelay = Math.floor(Math.random() * 1000);
if ($(element).css("opacity") < 0.3)
{
if (randomnum != 4)
{
if ($(element).css("opacity") != 0)
animation(element, 0, duration, randomdelay);
}
else
{
animation(element, randomopacity, duration, randomdelay);
}
}
else
{
animation(element, randomopacity, duration, randomdelay);
}
setTimeout(function () {
return changeopacity(duration, element);
}, duration + randomdelay);
}
function animation(element, randomopacity, duration, randomdelay){
$(element).clearQueue().stop().delay(randomdelay).animate({opacity: "0." + randomopacity}, duration);
}
function clickanimation(column, opacitylevel) {
var element = $(column).find("div");
$(element).clearQueue().stop();
$(element).animate({"background-color": "white"}, 200);
$(element).animate({opacity: "0." + opacitylevel}, 200);
$(element).delay(200).animate({opacity: "0.0"}, 500);
//$(element).delay(600).animate({"background-color": "black"}, 500);
}
答案 0 :(得分:2)
首要问题是您要为网页上的每个单元格创建一个setTimeout
。唯一能够处理Internet Explorer的浏览器,然后由于许多CSS更改导致缓慢重绘而失败。
我强烈建议您编写自己的事件调度程序。我在大学项目中使用过这样的东西:
var timer = {
length: 0,
stack: {},
timer: null,
id: 0,
add: function(f,d) {
timer.id++;
timer.stack[timer.id] = {f: f, d: d, r: 0};
timer.length++;
if( timer.timer == null) timer.timer = setInterval(timer.run,50);
return timer.id;
},
addInterval: function(f,d) {
timer.id++;
timer.stack[timer.id] = {f: f, d: d, r: d};
timer.length++;
if( timer.timer == null) timer.timer = setInterval(timer.run,50);
return timer.id;
},
remove: function(id) {
if( id && timer.stack[id]) {
delete timer.stack[id];
timer.length--;
if( timer.length == 0) {
clearInterval(timer.timer);
timer.timer = null;
}
}
},
run: function() {
var x;
for( x in timer.stack) {
if( !timer.stack.hasOwnProperty(x)) continue;
timer.stack[x].d -= 50;
if( timer.stack[x].d <= 0) {
timer.stack[x].f();
if( timer.stack[x]) {
if( timer.stack[x].r == 0)
timer.remove(x);
else
timer.stack[x].d = timer.stack[x].r;
}
}
}
}
};
然后,不要使用setTimeout
,而是使用相同的参数调用timer.add
。同样,您可以拨打setInterval
而不是timer.addInterval
。
这将允许您拥有任意数量的计时器,并且它们都将运行一个setInterval
,从而减少了浏览器的问题。
答案 1 :(得分:2)
好动画:-)然而,我发现了一些错误和可能的改进:
mouseenter
事件无效。我看不出所有这些元素都有id的原因。 html-string构建可能更简洁。
缓存元素!!!您正在几乎每个变量上使用jQuery
构造函数,构建一个新实例。只需重复使用它们!
您的changeopacity
函数看起来有点奇怪。如果不透明度低于0.3,那么动画为零的概率为1/13?这可能表达得更为严格。您也可以将不透明度缓存到变量,而不是每次都从dom中读取它。
没有理由将duration
和其他常量作为参数传递,它们永远不会改变,可以在全局范围内使用。
您应该使用complete callback of the animate
method而不是使用超时。超时永远不会准确,它们甚至可能会干扰导致(轻微)问题。
var duration = 2000,
tilesize = 40,
clickopacity = 0.9;
$(document).ready(function () {
filltable($("#tbl"), tilesize)
.on("click", "td", clickanimation);
$(".tile").each(function() {
changeopacity($(this));
});
$("#tbl div").mouseenter(function () {
$(this).clearQueue()
.stop()
.animate({opacity: "0.6"}, 800);
});
});
function filltable(tbl, tilesize) {
var win = $(window).width();
var horztiles = win.width() / tilesize;
var verttiles = win.height() / tilesize;
for (var y = 0; y < verttiles; y++) {
var tr = "<tr>";
for (var x = 0; x < horztiles; x++)
tr += "<td style='width:"+tilesize+"px;height:"+tilesize+"px;'><div class='tile' style='opacity:0;'></div></td>");
tbl.append(tr+"</tr>");
}
return tbl;
}
function changeopacity(element) {
var random = Math.floor(Math.random() * 13);
var opacity = Math.floor(Math.random() * 7);
var delay = Math.floor(Math.random() * 1000);
if (element.css("opacity") < 0.3 && random != 4)
opacity = 0;
element.clearQueue().stop().delay(delay).animate({
opacity: "0." + opacity
}, duration, function() {
changeopacity(element);
});
}
function clickanimation() {
$(this.firstChild)
.clearQueue()
.stop()
.animate({"background-color": "white"}, 200)
.animate({opacity: "0." + clickopacity}, 200)
.delay(200).animate({opacity: "0.0"}, 500);
//.delay(600)
//.animate({"background-color": "black"}, 500);
}