Forum Moderators: open

Message Too Old, No Replies

Expanding menus - cute, but slow as Molasses

A faster solution possible?

         

Josefu

7:51 am on Dec 28, 2007 (gmt 0)

10+ Year Member



I've divised a javascript that allows a (vertical) menu/list to "expand" to show sub-categories (and so on) when a list item is clicked. This animation is useful as it eliminates any viewer disorientation as the menu expands/collapses - and it looks nice, too.

The construction is a bit complicated, and involves php construction as well as ajax, but I will try to explain clearly its operation below; only the loop is the "slow" part, so I will post the code to that below. What happens is:

1) When a list item is clicked, it sends an ajax "refresh" query to the server (containing the ID of the category clicked, plus its "level" in the category heirarchy)
2) The server replies with the modified menu; each item has its own class depending on its "level" (category, sub-category, sub-sub category).
3) Next, javascript detects the classes to be expanded (in the ajax response), in a custom "getItemByClass()" function, sets them to zero, then expands these.

* the menu collapses when a higher-level category is clicked, but I left this out for clarity. Essentially the same function.

Here's the code:


function expandMenu(level) {
var speed = 3;
var minHeight = 0;
var maxHeight = 27;
var maxScroll = 0;
var curHeight = 0;
if (level == '0')
var element = 'level_one';
if (level == '1')
var element = 'level_two';
if (level == '2')
var element = 'level_three';
if (level == '3')
var element = 'level_four';
if (level == '4')
var element = 'level_five';

var toGrow = getElementsByClass(element);

for (var i = 0; i < toGrow.length; i++) {
toGrow[i].style.height = 0 + "px";
if (toGrow[i].scrollHeight > maxScroll) {
maxScroll = toGrow[i].scrollHeight;
}
}

var intId = setInterval(function() {
if (curHeight <= maxScroll) {
for (var i = 0; i < toGrow.length; i++) {
if (curHeight <= toGrow[i].scrollHeight) {
toGrow[i].style.height = curHeight + "px";
getHeight();
}
}
curHeight++;
} else {
clearInterval(intId);
}
}, 5);
getHeight();
};

...really, only the looping part is the problem, but I post all for better clarity. What happens is that the script "loops" through every item targeted to see whether they are fully expanded; once they are, the loop quits.

Now, this looks nice with faster CPU's and most browsers, but for slower machines and Firefox, the result is slow as molasses. I would like to find a means of speeding things up, but am not sure how; to be honest, I am still rather new to javascript, and do not fully understand the "setInterval()" function.

mehh

12:05 pm on Dec 28, 2007 (gmt 0)

10+ Year Member



Sorry, I made a mistake in posting

Josefu

12:01 am on Dec 31, 2007 (gmt 0)

10+ Year Member



I did manage to make one minor improvement: setting the setInterval() function to a tad more than 5 milliseconds, which may be too much for some CPU's. Around 25 milliseconds seemed to speed things up a bit, but even this may be too quick. Has anyone had any similar experiences with CPU-overloading through this function? Thanks for sharing.