kael.shipman Posted October 31, 2007 Share Posted October 31, 2007 Hey everyone, As a preface, I'll say that I'm running Firefox 2.0 on Mac OSX 10.4.10 and that the following problem is not quite so bad on windows, but does still exist. I've been having this problem for a few weeks now: I've built a whole arsenal of different functions and objects that all have the seemingly simple goal of extending and retracting a div (or other block-level element). However, the problem that they've all had has been rooted in the actual timing mechanism of the browser. I'd leave it at that and say that it's the browser's fault, but if you go to http://www.auctionpal.com/about/pal_facts, you'll see that the guy at stickman labs has utilized the Prototype library that comes with ruby on rails to produce the most beautifully smooth div roller that can be made. So I know it's possible! The most recent object is the most functional, yet is still posing problems (in two areas, but that'll be for later). It's an object called Drawer that has a head element and a content element. When you initialize a drawer, it automatically checks the provided content element's normal display length by switching the element to height (or width): auto, measuring the size with offsetHeight (or Width), then closing it back up to whatever the original css value was. This is the second issue that I was talking about, because if you have more than about 3 drawers on a page, the browser hangs for a little bit on each pageload while it switches the height to auto and back. Anyway, save that one for later. Here's the object definition: Drawer = function(head, cont, dimension, limits, speed, enforce) { if (!limits) limits = []; var self = this; this.open = false; this.head = head || this.head || false; this.content = cont || this.cont || false; this.rollSpeed = speed || 4; this.rollTime = 0; this.contentLowerLimit = limits[0] || 0; this.contentUpperLimit = limits[1] || false; this.contentUpperLimitEnforce = enforce || false; this.contentSize = 0; this.contentDimension = dimension || 'Height'; this.currentSize = 0; this.effect = 1; this.rolling = false; //timeout this.action = 0; //0 = bottom, 1 = moving up, 2 = top, -1 = moving down this.prepareDrawer(); this.checkContentSize(); } Drawer.prototype = { constructor : Drawer, prepareDrawer : function() { var self = this; if (this.head) addListener(this.head, 'click', function() { self.toggle(); }); }, checkContentSize : function() { var curDimension, styleProp = this.contentDimension.toLowerCase(); this.currentSize = this.content['offset' + this.contentDimension]; if (!this.content) return false; if (this.contentUpperLimit && this.contentUpperLimitEnforce) { this.contentSize = this.contentUpperLimit; return; } curDimension = this.content.style[styleProp]; this.content.style[styleProp] = 'auto'; this.contentSize = this.content['offset' + this.contentDimension]; this.content.style[styleProp] = curDimension; }, toggle : function() { var self = this; if (this.rolling) clearInterval(this.rolling); if (this.action == 0 || this.action == -1) { this.action = 1; this.comparison = this.contentUpperLimit || this.contentSize; } else { this.action = -1; this.comparison = this.contentLowerLimit; } this.rolling = setInterval(function() { self.controlAction(); }, 2); }, moveDrawer : function() { this.currentSize = this.currentSize*1 + this.action * Math.pow((this.rollTime * this.rollSpeed / 4), 3); if (this.currentSize * this.action > this.comparison * this.action) this.currentSize = this.comparison; this.content.style[this.contentDimension.toLowerCase()] = this.currentSize + 'px'; return; }, controlAction : function() { if (this.currentSize != this.comparison) { this.moveDrawer(); this.rollTime++; return; } else { clearTimeout(this.rolling); this.action = this.action*1 + 1; this.rollTime = 0; return; } } } I admit the constructor is terrible, but that's because I drew it all up pretty quickly last night and then mashed it all over the place to fit my needs tonight. You can see this in action at http://64.78.46.106 (sorry for the ip; the domain stuff isn't configured yet) in the "posted comments" section. Click on a "more" link and the thing rattles its way down. Anyone have any ideas on how that accordion by stickman might differ from mine? I've been making these as light-weight as possible, but they just plain and simply don't scale well. It works great when there's only 2 or 3 of them, but as soon as you go past that, the thing falls apart. Thanks in advance. -kael Quote Link to comment Share on other sites More sharing options...
mainewoods Posted October 31, 2007 Share Posted October 31, 2007 download prototype.js and dissect it! I did that and learned a few things. Definitely is well written code. Quote Link to comment Share on other sites More sharing options...
kael.shipman Posted November 2, 2007 Author Share Posted November 2, 2007 Yeah, probably wasn't a good idea for me to start reverse engineering from a "subclass" of a much larger and more feature-packed parent. I think I'll take your advice! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.