2011-10-05, 11:29 PM
I've got an animated collapse function that's designed to be more or less a drop in replacement for MyBB's collapse javascript, but I've got a bit of a problem. It's not as good as it should be in Firefox, even though it's smooth in IE. I have not yet had a chance to try it in other browsers. Currently it should animate in ~30ms steps, though I've designed it so that it can use variable time steps (so that on a slow computer it still only takes ~250ms to close).
I was wondering if anyone could help me improve my code's performance, mainly in the animation update functions.
Here's the code. For those not familiar, '~' is a bitwise inverse operator that I'm using twice to trim floats to ints for the height pixel count, rather than Math.round().
The key things I'm looking at is doExp() and doCol(), though collapse() might be part of problem:
I was wondering if anyone could help me improve my code's performance, mainly in the animation update functions.
Here's the code. For those not familiar, '~' is a bitwise inverse operator that I'm using twice to trim floats to ints for the height pixel count, rather than Math.round().
The key things I'm looking at is doExp() and doCol(), though collapse() might be part of problem:
var togglables = {
togglers: Array(),
// Variable so I can override on a per-theme basis
aniLength: 250,
i: 0,
init: function()
{
togglables.togglers = $$('img.toggle');
if(togglables.togglers.length == 0)
return true;
togglables.togglers.each(function(toggler)
{
if(!toggler.id)
return;
toggler.indexID = togglables.i++;
toggler.target = $(toggler.id.replace("_img", "_e"));
if(toggler.target.style.display == "none")
toggler.alt = '[+]';
if(MyBB.browser == "ie")
toggler.style.cursor = "hand";
else
toggler.style.cursor = "pointer";
Event.observe(toggler, 'click', togglables.toggle.bind(togglables));
}.bind(this));
return true;
},
toggle: function(e)
{
element = Event.element(e);
if(element.isMoving)
return;
element.target.style.margin = "-1px 0 0 0";
if(element.alt == '[-]')
{
element.alt = '[+]';
element.src = element.src.replace(".gif", "_collapsed.gif");
this.collapse(element, -1);
}
else
{
element.alt = '[-]';
element.src = element.src.replace("_collapsed.gif", ".gif");
this.collapse(element, 1);
}
},
collapse: function(element, dir)
{
element.isMoving = true;
element.moveDir = dir;
element.aniStart = (new Date()).getTime();
element.target.style.display = "block";
element.realHeight = element.target.scrollHeight;
element.target.style.overflow = "hidden";
if(dir == 1)
{
element.target.style.height = "1px";
element.aniTimer = setInterval('togglables.doExp(togglables.togglers[' + element.indexID + ']);', 30);
}
else
{
element.aniTimer = setInterval('togglables.doCol(togglables.togglers[' + element.indexID + ']);', 30);
}
},
doExp: function(element)
{
var elapsed = (new Date()).getTime() - element.aniStart;
if(elapsed < togglables.aniLength)
element.target.style.height = (~~((elapsed / togglables.aniLength) * element.realHeight)) + 'px';
else
togglables.stop(element);
},
doCol: function(element)
{
var elapsed = (new Date()).getTime() - element.aniStart;
var rh = element.realHeight;
if(elapsed < togglables.aniLength)
element.target.style.height = (rh - ~~((elapsed / togglables.aniLength) * rh)) + 'px';
else
togglables.stop(element);
},
stop: function(element)
{
clearInterval(element.aniTimer);
if(element.moveDir == -1)
element.target.style.display = 'none';
delete element.aniTimer;
element.isMoving = false;
if(element.moveDir == -1)
togglables.saveCollapsed(element.id.replace("_img", ""), 1);
else
{
element.target.style.overflow = "inherit";
element.target.style.height = "auto";
togglables.saveCollapsed(element.id.replace("_img", ""));
}
},
// Taken from MyBB's implementation
saveCollapsed: function(id, add)
{
var saved = new Array();
var newCollapsed = new Array();
var collapsed = Cookie.get("collapsed");
if(collapsed)
{
saved = collapsed.split("|");
saved.each(function(item) {
if(item != id && item != "")
{
newCollapsed[newCollapsed.length] = item;
}
});
}
if(add == 1)
{
newCollapsed[newCollapsed.length] = id;
}
Cookie.set("collapsed", newCollapsed.join("|"));
}
};