Understanding the libraryAs mentioned before the reason we want to use a library is
to take care of the most basic browser differences and
concentrate on making the real code. The library has a lot of methods built in that we can reuse at any time. So when we need to make a script, effect or a menu that's special for one site we just include the library (with the functions you need) and start coding.
In this tutorial we'll make a simple but cute dragable menu script where we can drag the "head" of the menu and the rest slides after it. It's important that you
understand the basics about how the library works to be able to follow this tutorial, so if you haven't please read the DHTML Lib tutorial.
Then let's start coding! Starting with HTML and stylesWe'll start by thinking a little about how to add our DIV tags. We need two mayor divs, one for the head part and one parent div for all the items. Then we'll have one div for each item inside the parent div (in this example we'll make 4 items).
At this point we should also think a little about how the menu should behave on events that occur on the divs. Here's a little overview:
So we'll start with the HTML code to add inside the
body tag:
<> Menu< >
<>
Then we need to give the divs some styles:
<>
We place that style tag in the head of our page.
I wont talk much about these styles settings now, if you know a little CSS it should be pretty simple to follow. The height,widths and clipping are taken from FIG 1 that where made before I started making the menu.
As you can see I have added cursor definitions (NOTE: Setting the cursor only works in Explorer 4+ and Netscape 6) and set the background colors. I set clip values to the same as height and width and layer-background-color
to make NS4 cover the entire div with the background color.
Then we are ready to start with the fun part, the scripting.Making the scriptWe start with the easy part, adding a reference to out lib.js file in the head part of our page. (if you haven't downloaded it yet, see the lib page)
Like this:
<>
Now we have the libary ready and can start with the code for the menu. First I want to make some global variables for the script. That can be easily changed:
numItems - The number of menu items we want to have.
itemOnColor - The background color to change the item to onmouseover
itemOffColor - The background color to change the item to onmouseout
So we set them like this:
numItems=4
itemOnColor="red"
itemOffColor="silver"
We also need to be able to control where each item goes when clicked so I add an array with links:
itemLinks=new Array()
itemLinks[0]="" 'Note that arrays always start at 0
itemLinks[1]="http://www.bratta.com"
itemLinks[2]="http://www.yahoo.com"
itemLinks[3]="http://www.altavista.com"
The next part of the script is be a init function where all the library objects are made, the placement of the layers are fixed and the script will start:
function init(){
oHead=new lib_obj('divHead')
oMenu=new lib_obj('divMenu')
oMenu.bg(menuBgColor)
oHead.dragdrop()
oItems=new Array()
var h=0
for(i=0;i<
This function should be called to "start" the menu script, so either onload or just after the HTML divs are loaded.
Let's go line by line:
oHead=new lib_obj('divHead') - Here we make a new lib object called oHead which
references the div called divHead.
oMenu=new lib_obj('divMenu') - Here we make a new lib object called oMenu which
references the div called divHead.
oHead.dragdrop() - Set drag and drop support for the oHead object.
Then we make a new array which will contain all the items for the menu
oItems=new Array()
The we loop the array once for each item. Remember that we set the numItems variable above
to 4, so this line for(i=0;i< means that we want to loop from 0 to 4.
The reason we use a loop here is because it makes smaller code and that it should be easy to add more
elements (just add another HTML div and change numItem to 5).
Inside each loop we start of by making each oItem[i] object (i is the counter for the loop):
oItems[i]=new lib_obj('divItem'+i,'divMenu'), then we move the object
to left 0 and top h. As you see above h=0, on the line below
h+=oItems[i].h we add the height of each element to the h variable
so the item will be moved to the height of the previous item. That way the items
will be below one another. After that we set the default background color oItems[i].bg(itemOffColor).
Now comes a little interesting part of the code; each lib object has a property called evnt that
we use to set events for the object. We remember from FIG 1 that we wanted a onmouseover and
a onmouseout event for the item divs that should change the background colors, we will make those functions
in a little bit. An event handler set like this doesn't support any arguments to a function, that's why
we attach the event to a new Function, the argument we want to pass is the number of
the current item, so we go like this: oItems[i].evnt.onmouseover=new Function("mover("+i+")").
After that we set the onclick event which will make the page go to the the link for that item when clicked.
Netscape 4 doesn't support onclick events on layers, so we have to use onmousedown, but first we have to
capture the event for that div (ref points to the document of that div) oItems[i].ref.captureEvents(Event.MOUSEDOWN), then add the event:
oItems[i].ref.onmousedown = new Function("location.href=\'+itemLinks[i]+'\'"). For all other
browsers we just set the onclick event like this: oItems[i].evnt.onclick=new Function("location.href=\'+itemLinks[i]+'\'")
We then end by clipping the main menu object to the same height and width as all the items: oMenu.clipTo(0,oMenu.w,h,0,1)
The last line in this function starts another function that will always check if the menu is moved. I will explain that function
in a little bit.
Now we'll make the mover and mout functions that will be called onmouseover and
onmouseout of each item. They are pretty straight forward and look like this:
function mover(i){
oItems[i].bg(itemOnColor)
}
function mout(i){
oItems[i].bg(itemOffColor)
}
The argument is the number of the item that calls the functions. Then we just set the background color
to the itemOnColor or the itemOffColor variables that we defined earlier.
The last but most important function moveM2 (called from last line in init above)
looks like this:
function moveM2(inc){
endx=oHead.x;
endy=oHead.y+oHead.h
x=oMenu.x;
y=oMenu.y
distx = endx - x;
disty = endy - y
num = Math.sqrt(Math.pow(distx,2)+Math.pow(disty,2))/inc
dx = distx/num;
dy = disty/num
if((Math.floor(Math.abs(dx))<
This function will loop itself and run all all the time while the user is on the page. Is basically just
checks if there is a difference between the oHead object position and the oMenu object position,
and if there is it will slide the oMenu object to the correct position.
So when you drag the oHead object this function will notice that there is a difference between the positions
and "fix" it. It has one argument; inc
which helps us control how fast the oMenu object will slide.
Again we'll go line by line:
The first four lines just set some varibles so it will be easier to follow below:
endx=oHead.x - The x (left) position that the slide will end at.
endx=oHead.y+oHead.h - The y (top) position that the slide will end at.
x=oMenu.x - The current x (left) position of the oMenu object.
y=oMenu.y - The current y (top) position of the oMenu object.
Then we have two lines that figures out the distance we need to slide for x and y:
distx = endx - x, disty = endy - y.
The next line is pure good old fashion math, to get the slide to move correctly (we want
the left and the top "sliding" to end at the same time) we find the number that we will
divide the distance with to get the x and y to move the correctly number of pixel each time.
We take the square root of the the distance powered by 2 and divided by inc:
num = Math.sqrt(Math.pow(distx,2)+Math.pow(disty,2))/inc
The next step is to get the actual pixels to move for x and y;
dx = distx/num; , dy = disty/num;
We are now ready to start and check whether we should move the menu, I'll take
part one of this line first:
Math.floor(Math.abs(dx))<
Math.floor just rounds the numbers and makes them integers (rounds down
to nearest hole number). Math.abs makes the number positiv no matter
if it's a negative number or not, we need this because we want the menu to move
both ways, left and right (or up and down). So this line basically says:
if the number of pixels to move x position is lower then the
position to end at minus the current position - go on. The second
part of that line does the same thing for the y position.
If that line evaluates to true we will move the menu
by dx and dy pixels: oMenu.moveBy(dx,dy).
If it doesn't evaluate to true we just move the menu straight to
the endx and endy.
Ok, one line left, this is an easy one; setTimeout("moveM2("+inc+")",20) -
it's a timeout that calls this function every 20 milliseconds.
Why do we do that you might ask, well there are lots of different ways
we could have done it for instance called the function only when the oHead
is dragged or similar, but believe me; to make it as stable as possible this is
the best way to go. Netscape 4 doesn't support clearTimeout very well
and if we did it another way there's a pretty big chance we would have gotten
some problems with multiple timeouts trying to do the same thing. Though
timeouts are pretty heavy on the system it's ok as long as you
don't have a lot of them going at the same time. Anyway, after that
little side track I have good news; We are done!
Now we just need to paste it all together into one page and we have
ourselves a brand new DHTML script.The code
<>
<>
<>Drag menu from DHTMLCentral.com<>
<>
<>
<>
<>
<>
<> Menu< >
<>
Regular content goes here
<>
<>
Note that you need the lib.js file that can be found in the DHTML library in the same directory of your file for this to work.
Good luck!Copyright ©2000-2002 DHTMLCentral.com, Bratta Communications. All rights reserved.
|