(right-click on a link)
If this does not work, see the section Browser compatibility below.
There are plenty of context menu examples out there that simply add a context menu for the whole page. While this can useful, I find it much more useful to have item-specific context menus. For example, one might only want to target hyperlinks or list items. This example only targets hyperlinks, but it is extremely easy to change. In addition, one can disable the context menu quite easily, so that power-users can regain the extra functionality their browser provides.
The relevant events are the body's onMouseDown and onContextMenu.
The first is required in order to hide our custom context menu at the proper time.
The latter is required for telling the browser not to show its own context menu.
While the events could go in the <body> tag, I have decided to use
the preferred method of wiring them up in an initialization function: InitContext().
It is important to return false; in the function that handles the onContextMenu
event if you want to suppress the browser's context menu.
Two important events are attached to the context menu: onMouseOver and
onMouseOut. We use these to keep track of whether the mouse is
over the context menu. This lets us take action if the context menu has been
clicked, and to either show it somewhere else or make it disappear when something
else is clicked.
The context menu is simply a div element with display
set to none and position set to absolute.
I added a border, but that wasn't necessary. If the the position
attribute is not set, the menu will shift other elements around when it appears;
definitely not what you want.
Note the aDisable hyperlink above with text "disable this menu"; this
exists to allow the user to regain normal right-click functionality. The
corresponding aEnable hyperlink is located near the top of the document,
but can be located anywhere. It re-enables the custom right-click functionality:
I use three global variables and one global variable that's just an easier way to
refer to the context menu div:
The functions should be self-explanatory -- if you disagree, tell me what's unclear. Two hacks were necessary in order to target standards-compliant browsers and remain compatible with IE:
document.body.scrollTop, but IE uses
document.documentElement.scrollTop.window.event.The CSS below is not required for anything to work, but it does give the context menu in this page the look and feel that it has.
Overriding the default right-click functionality browsers provide is a very questionable business. Deviating from standard interface guidelines means that it will be harder for users to use the functionality you add by breaking standard interface rules. I have two responses to this: 1) it is easy to make this standard by turning it into a left-click-on-an-image; 2) sometimes the default isn't the best. Take this as you will; I provide it so that if people want to implement this, they can implement it in a fairly clean manner.
Note that unless your context menu actions either change the page or explicitly hide
the context menu, you will have to do so manually; use CloseContext() to do so.
There is no reason to wire the body's onmousedown event handler
if you want to use left or middle click, as the browser's context menu only pops up on
right click. While the code above may work with left/middle click, one could also simply
wire up onclick for processing left clicks; this is actually required for hyperlinks,
as otherwise they will work like hyperlinks normally do. Because browser makers love
incompatibility, the codes for event.button vary from browser to browser;
see the below table for values and feel free to provide me with additional rows
for other browsers.
| Browser | Left Click | Middle Click | Right Click |
|---|---|---|---|
| Firefox | 0 | 1 | 2 |
| Internet Explorer | 1 | 4 | 2 |
Note that IE uses the values 1, 2, and 4 so that one can determine every mouse button that is pressed; Firefox does not allow this.
This context menu will not work in browsers that disallow overriding of the context menu by default. It appears that some versions of Safari and Opera might do this -- I suspect there is a setting that allows the user to change this behavior. IE, Firefox, and Google Chrome appear to allow such overriding by default. As noted above, it is easy to change from right-click to left-click, ctrl-left-click, or something like that.
In Firefox, the relevant setting is here: Tools->Options->Content->Advanced->Disable or replace context menus. (Use the first advanced button.)
If you found this tutorial helpful, please link to it. If you really want to show your appreciation... :-)