|
home / documentation / reference / mini-tutorial: custom transitions
Custom Transitions
HierMenus version 6 introduces Menu Event Hooks, triggers that will fire your
own custom developed JavaScript code at key points in HierMenus processing. This
custom developed code allows you to synchronize some type of non-HierMenus activity
with HierMenus, such as resizing an image to the exact size of a menu just after the
menu has been created, or displaying, moving, and hiding additional custom elements
of the page when certain menus are displayed, moved, or hidden. Since most event hooks
are implemented as methods of the menu or item objects they are applied to, advanced
developers can even interact with HierMenus' own menu configuration parameters for the
menu or menu item via the this keyword of their custom functions. In this
mini-tutorial, we'll be focusing on two specific Menu Event Hooks: setTrans
and killTrans. For further discussion of Menu Event Hooks in general, have
a look a the Menu Event Hooks Mini-Tutorial.
setTrans And killTrans Are Different
The setTrans and killTrans event hooks differ substantially from
other HM event hooks, both in name and functionality. Other event hooks have names such
as HM_OnMove and HM_OnVisibilityToggle. setTrans
and killTrans are named as they are to alert you to the fact that they have
a key functional difference from most other event hooks. Specifically, the other event
hooks are intended to complement (or perhaps, in advanced circumstances, modify) HierMenus
own behavior where the hook is applied. For example, if you hook a menu's HM_OnVisibilityToggle
event, then you can synchronize the visibility of your own custom elements to a HierMenus
menu. But you can't, simply by hooking HM_OnVisibilityToggle, prevent HierMenus
from actually performing the visibility toggle on the menu. The lone exception to
this rule is HM_OnLink, which will, if it returns false, prevent HierMenus
from following a menu item link.
When you hook setTrans, however, you are not merely augmenting the standard
functionality of HierMenus, you are instead replacing it. Specifically,
setTrans allows you to completely take over the process of displaying
(making visible) and hiding a menu, or menus, on the page. Because of this interaction, it
is very important when you design your own custom transitions via setTrans and
killTrans that you fully understand what HierMenus will expect from your
setTrans and killTrans methods, and how HierMenus interacts with them.
A Simple Example
As their names imply, your setTrans method should be used to setup (prepare for
and begin) your menu transition effect; while killTrans should "fast forward" a
currently in-process transition immediately to its conclusion. HierMenus will call your
setTrans method at the point where it would normally toggle the visibility of
the menu. But since HierMenus does not know where (at what point in the transition)
a specific menu effect is, it simply calls killTrans anytime it needs to
immediately "finish" a transition without having to wait for your own custom transition
effect to complete. Times when HierMenus needs to immediately complete a transition are
many and various; but as a general rule if HierMenus needs to move a menu to a new location
(such as may happen on a window resize) or if it needs to redisplay a menu it will be
sure to call the killTrans method of the menu first. HierMenus does not know where
your menu transitions are and thus it calls killTrans whenever it needs to be
sure the transition is complete; and conversely, you do not know all the places where
HierMenus might call killTrans, therefore you must code your method appropriately.
With these rules in mind, let's create a simple menu transition that does nothing more
than emulate HierMenus' default behavior; that is, let's create a setTrans/killTrans
method pair that will appropriately make the menu visible or hidden depending on HierMenus'
needs. The following two functions accomplish precisely this.
function HM_fc_SetTrans(show) {
this.visibilityToggle(show);
}
function HM_fc_KillTrans() {
return;
}
This is as simple as a custom transition gets. In our setTrans method, we simply
call HierMenu's own visibilityToggle method to make the menu visible or hidden based
on the passed in show parameter. We recommend you also use visibilityToggle
to ultimately hide and show the menu when your transition effect is complete, so that the
HM_OnVisibilityToggle event hook (which is called from the visibilityToggle method)
will be properly fired. Additionally, HierMenus masks any cross-browser coding required to
show/hide menus; so you can call visibilityToggle without concern for the browser
your code is executing on.
Our killTrans method is even simpler than setTrans: in a word, our
killTrans method does nothing. The reason for this is because our setTrans
method performs the entire menu transition in question; when setTrans is
finished, the transition is finished. Therefore, killTrans needn't perform any
"clean up" after the menu transition has been completed.
Having defined our custom transitions, all that is left is to assign them, which we
do in the configuration file:
setTrans:HM_fc_SetTrans,
killTrans:HM_fc_KillTrans,
When naming your custom functions, be sure to choose a name that will not
conflict with HierMenus--or your own--JavaScript naming schemes. HierMenus
does not use the HM_fc prefix on any of its own internal functions or
variables, so it is a safe choice; as would be most schemes that do not
begin with the HM_ prefix (which is used on nearly all HierMenus global
variables and functions).
Before we continue this discussion, note one other important side effect
of applying your custom transitions. Using setTrans will nullify any Internet
Explorer specific filter based transitions (that you applied via the IEShowTransition
and/or IEHideTransition parameters). That is, such filter based transitions will
not be applied to the menu when your own custom transitions are in effect. If you wish to
use Internet Explorer filter based transitions, you will need to either account for this
in your own custom code, or set the setTrans/killTrans hooks conditionally in
your confguration file. For example:
setTrans:(window.HM_IE55)?null:HM_fc_SetTrans,
killTrans:(window.HM_IE55)?null:HM_fc_KillTrans,
Delayed Popups Example
Let's have a look at a slightly more complex example. In HierMenus, the HoverTimeMilliSeconds
parameter allows you to set a slight delay before a child menu appears. I.E., the user must hold
their mouse over a parent item for HoverTimeMilliSeconds before a child menu will
actually popup for that menu item. While perfect for child menus, HoverTimeMilliSeconds
will not work on top-level popup menus; menus that appear when the user rolls over a link
in your Web page. Perhaps a custom transition can apply this effect for us. Have a look at the
following methods:
function HM_fc_SetTrans(show) {
this.eMenu.hmc_VisSetting=show;
if(!show) HM_fc_VisToggle(this.MenuID);
else this.eMenu.hmc_VisTimer=
HM_MenusTarget.setTimeout("HM_fc_VisToggle('"+
this.MenuID+
"')",this.hmc_VisMilliSeconds);
}
function HM_fc_VisToggle(menuID) {
if(HM_o_Menus) {
var theMenu=HM_o_Menus[menuID];
if(theMenu&&theMenu.eMenu) {
theMenu.eMenu.hmc_VisTimer=null;
theMenu.visibilityToggle(theMenu.eMenu.hmc_VisSetting);
}
}
}
function HM_fc_KillTrans() {
if(!this.eMenu||!this.eMenu.hmc_VisTimer) return;
HM_MenusTarget.clearTimeout(this.eMenu.hmc_VisTimer);
this.eMenu.hmc_VisTimer=null;
}
While simple in concept, the above routines illustrate several key concepts of custom
transitions. They also introduce several HierMenus specific parameter settings and code
techniques that you can use to manipulate your own menus.
All of our custom object properties begin with hmc_, to avoid possible
conflicts with HierMenus own properties (or properties that may exist on the HTML
element being referred to).
Our setTrans function saves, and then examines the show parameter
passed from HierMenus. If it is false (the menu is supposed to be hidden) then
the menu is immediately hidden (our custom HM_fc_VisToggle routine is executed
immediately). If it is true (the menu is about to be displayed), then
a timer is set that will call HM_fc_VisToggle after a set number of milliseconds.
Both the initial visibility setting for the menu (hmc_VisSetting) and the
timeout identifier (hmc_VisTimer) are set directly on the HTML element for
this menu (this.eMenu) to avoid menu synchronization problems in Opera
cross-frame implementations. The timeout is set in the window the menu will actually
appear in (represented internally in HierMenus via HM_MenusTarget) to avoid
cross-frame timeout synchronization problems in Opera. Finally, two other menu parameters
are utilized: this.MenuID refers to the MenuID of the menu, and
this.hmc_VisMilliSeconds refers to the number of milliseconds we should
wait before displaying this menu. You won't find hmc_VisMilliSeconds in our
standard HierMenus reference material, since it is not defined by HierMenus. Instead,
you would define it yourself by adding the parameter to the appropriate HM_f_SetMenus
call when the menu is defined. See the setup instructions
and the example registration below.
Our killTrans function is quite simple. Since the only menu transitions
that would need to be "killed" are menu displays (remember that menu hides happen immediately
from setTrans), we check the value in hmc_VisTimer. If it is null, then
we return immediately. Since our HM_fc_VisToggle routine clears this value, whenever
it is null, we can assume that our transition is already complete. If, however, it has a
valid value, then we immediately cancel the timeout and clear the variable to avoid confusion
the next time setTrans is called.
Note that normally in killTrans, we would instead immediately
display the menu after we cancel the timeout (i.e., instead of nulling hmc_VisTimer
we would directly call HM_fc_VisToggle to ensure that the menu transition completes
the way we initially expected it to). In this case, however, we know that the only menus
we are going to apply the custom transition to is top level popup menus; and in the
case of those menus, if we have need to kill the transition prematurely then we may
as well not display the menu at all. Such assumptions should generally not be made; but
in this case it should be safe. If you do vary from the standard path of immediately
finishing a started transition in killTrans, be sure you know what you are
doing (and be sure that you test your result thoroughly in multiple browsers).
Finally, the actual code that will execute our transition logic is in HM_fc_VisToggle.
This function first located the appropriate menu object from the passed in ID via HierMenus'
own HM_o_Menus object, which contains a property for each defined menu referenced
by the menu's id. If the resulting menu is a valid HM definition (theMenu) and
that menu definition has a defined HTML element (theMenu.eMenu) we proceed to
clear the timer variable (to let killTrans know that the timer has been processed)
and call HierMenus' own visibilityToggle method for the menu to actually display
it. At this point, our custom transition is complete.
Assigning this custom transition to a menu would look something like this:
setTrans:HM_fc_SetTrans,
killTrans:HM_fc_KillTrans,
hmc_VisMilliSeconds:600,
HierMenus transfers all properties encountered in configuration objects to its
own appropriate, internal object whether it recognizes them or not (in fact, it
doesn't even attempt to recognize them initially). This is how the
hmc_VisMilliSeconds variable above can be applied to menu definitions. Even
though HM doesn't use it itself, it still passes it to the menu object definitions
(assuming we added it in a HM_f_SetMenus, HM_f_SetMenuTemplate,
or HM_f_UpdateDefaults call), allowing us to later access them within our
own event hooks.
Have a look at the results of the above transitions by rolling over the
following three links. In each case, you'll have to hover over the link for
just over half a second (600 milliseconds) before the menu actually appears
Menu 1
Menu 2
Menu 3
Sliding Menus

To conclude this mini-tutorial, let's have a brief look at the custom functions included
in the HierMenus 6 loader file that implement sliding menus. We do not intend to dwell at
length on these functions (indeed, the majority of their processing steps are similar to the
popups example above) but we wanted to point out a few specific techniques that may be
helpful to you in your own custom transition designs. The menu above is a working example of
a sliding menu; the first child menus are all SlideInFrom/SlideOutTo top, while the
grandchild menu of child menu 1 is SlideInFrom/SlideOutTo left. Before continuing
with this discussion, you may wish to examine the HM_f_SetSlide and
HM_f_KillSlide functions in your HM_Loader.js file for yourself.
Sliding menus are implemented via the SlideInFrom and
SlideOutTo parameters, as well as registering the
setTrans and killTrans hooks
themselves. See the reference entries (click the links) for each of these parameters for
further details.
We disable some browsers from sliding menu processing, because we found after
testing that those browsers did not display the sliding effect consistently enough for our needs.
For those browsers that are excluded, we simply call the menu's visibilityToggle
immediately (see the above examples for more on visibilityToggle).
The SlideInInterval, SlideOutInterval,
SlideInPercent, and SlideInPercent
parameters allow you to control the sliding effect on a menu by menu basis. Each of these
is interrogated in HM_f_SetSlide, and for those that do not exist a default is
provided. Providing a default for your own custom parameters such as these is strongly
recommended; to avoid having to rely on valid default values passed from the menu
configuration.
Some internal HierMenus variables referred to in our sliding menus routine exist
in different places for different browsers. This is unfortunate, but necessary to
accomplish some tasks. For example, in Opera the HasChildVisible variable
exists on the menu element; in all other browsers it is on the menu object itself.
It must be stated here that we will not document every internal structure of the
HierMenus script; if you choose to reference HierMenus internal variables or methods
(such as HasChildVisible and hideChildren, like we do in our
HM_f_SetSlide) in your own coding schemes then you must do so at your
own risk (though we will, of course, attempt to keep variables in the same place as
best as possible in subsequent version 6 releases).
SlideStatus is used to track the status of the transition. It is
cleared when the transition is complete. This allows us to know, in killTrans,
whether there's anything left to do.
In our main animation routine HM_f_SlideMoveTo, we first check to be
sure the page is still accessible before we attempt to do anything. This is necessary
for cross-frames implementations, but not necessary for stand alone implementations.
If you're designing for cross frames you should include this check in any function
that will be called from an event handler (or a timeout) to avoid the target document
from being unloaded out from in under your timeout delay. In later browsers (Opera, IE5+,
Gecko) you can use the same check we do:
if(HM_IsReloading||!HM_f_DocumentCheck()) return;
In older browsers you'll need to account for this possibility yourselves.
As is appropriate, our killTrans method finishes our transition
(immediately moves the menu to its original, pre-transition location and then hides
or displays it as appropriate). Again, it is important that your killTrans
method be allowed to do its work based on the original transition as prepared
and launched by setTrans. Otherwise, you run the risk of HierMenus own
internal processing getting out of sync (thinking that a menu is currently displayed
when it isn't, for example). And remember to check your own status markers, too;
if your transition is already complete, you should just return from killTrans
immediately.
Here's a (partial) example of a menu configuration that uses the custom sliding
routines:
SlideInFrom:"top",
ScrollEnabled:1,
SlideInPercent:15,
SlideInInterval:10,
Notice that in this example (and in our working example above), we've not used
the SlideOutTo parameter settings. So our menus will slide into position when
displayed, but hide immediately. This is our recommended way to use sliding menus, as
too much menu movement on the page (as would be the case if a menu were both sliding
in and out) can be distracting or annoying to site visitors. Also notice that
ScrollEnabled is set to true for our sliding menu. This is necessary, as our
custom sliding routined rely on a menu structure that is only valid within
scrollable menus.
For more information on sliding menus, see the individual parameter reference
entries themselves:
SlideInInterval
SlideOutInterval
SlideInPercent
SlideOutPercent
SlideInFrom
SlideOutTo
setTrans
killTrans
|