So, in a lot of my web projects I find myself using javascript to create windows that mimic that mimic the windows in, well, Windows. This may be a popup window that looks like an explorer window or a right-click menu that looks like a context menu. Recoding the whole thing every time is a pain in the butt, so I wanted to write a library of sorts. I've also been wanting to learn OO in javascript since it's so monstrously different than OO in php and c#.
Anyway, this is where I am. Here's a link to a demo. It's not done... it's not even close to done. I've run into a lot of serious problems. But more on that later.
demo:
http://clankiller.com/jsWindow/
zip download:
http://clankiller.com/jsWindow/js_windowObject.zip
Click on "create" to dynamically create a window. The location, size and content are all static, this is just a demo. But notice it's possible to drag the window around even to resize it. Also, dragging and resizing is 'buggy'. I guess I should post the code first.
This is the class and the meat of the monster.
this is the function that creates the object and sets its variables. This is the part a user would have to mess with.
And for completeness here's my html
And css
Here are the stumbling blocks.
1. After I instantiate an object, how do I associate an onclick event handler (or any other js event) with that specific instance of the object. The this keyword wouldn't work, since that would just refer to the element the event occured against. What I ended up doing was storing all the objects in an array (the o array). I pass an object's id (its position in the o array) to the object which then stores it as a local variable. I also store everything that can be acted on (the window, the title bar, the status bar) as object references inside the object. Then with the onclick, for instance, I just reference objectarray[objectid].element, like o[id].status.innerHTML = "This is the status".
I think that's a pretty big hack. The more elegant way would be for the event to automatically reference the object. Still, even though it's a hack the only thing external to the object is the array. So I guess that's a good thing.
2. Dragging.. for the window resizing and window moving, what I've done is add onmousedown, onmouseup and onmousemove event handlers to the specific sections. The onmouseup sets a local variable that says "drag" or "resize". Without those local cars set the onmousemove just returns... with it set it then does its magic of sampling the location of the window in respect to the mouse cursor and moves/resizes the window object as appropriate.
But it's not very reliable. The problem, I think, is the sampling rate of the onmousemove event. Say it samples even 100ms.. if your mouse traverses off the edge of the onmousemove element in that 100ms the events stop firing. In effect, if you move your mouse too fast, or even if your mouse is just too close to the edge of the element, you lose your "grip". Then when you mouse back over, regardless of the mouse button position, it snaps back on.
There are a few things wrong with this. 1, the onmousemove event handler is always on, it just immediately returns false. This is probably excessive. I'm thinking about dynamically adding the onmousemove event handler when onmousedown happens. Regarding the sample rate problem, I'm thinking that onmousedown I might just dynamically create an element, make it completely transparent and like 200px x 200px, then center it on the mouse. The onmousemove event handler would be attached to this element. Then onmouseup I just remove that element. This gives a bigger hit box.
so anyway, that's where I am. Those are my big problems. It lacks elegance and it acts a bit wonky... the wonky bit at least I think I can fix. It's also pretty limited right now... just one window type. I plan on adding a context menu type window as well. Between that and the fact you can turn on and off various elements (like the status and menu bars) should make it pretty useful. Oh, and right now I don't statically set the height and width but I think I will. This'll allow long, wrapping text without just making the window retardedly wide.
If anyone has any input or improvements I'd love to hear it.