You want to add a custom context menu to an element, so you add a "contextmenu" event listener to the element. That listener is going to do two basic things:
The code will look something like this:
function onContextmenu(e) {
e.preventDefault();
if (!contextmenu) {
contextmenu = new Y.Overlay({
bodyContent: "<ul class=\"contextmenu\"><li>Option 1</li><li>Option 2</li><li>Option 3</li></ul>",
visible: false,
constrain: true
});
contextmenu.render(Y.one("body"));
}
contextmenu.set("xy", [e.pageX, e.pageY]);
contextmenu.show();
}
btn.on("contextmenu", onContextmenu);
This code will work great if the "contextmenu" is triggered via the mouse. However, the "contextmenu" event is one of those device-independent events: can be triggered via the mouse, or the keyboard (on Windows using the Menu key, or the Shift + F10 shortcut). When it's triggered via the keyboard you will run into problems. Here's an overview of the obstacles and inconsistencies by browser + platform:
Here's a working example. The following button has a custom context menu. Try to invoke it via the keyboard to see the problems yourself:
Returning to the task at hand, as a developer you just want to bind a single "contextmenu" event listener and have it do the right thing regardless of how the event was triggered. This is what the "contextmenu" synthetic event does; it fixes all the aforementioned problems and inconsistencies while maintaining the same signature as a standard "contextmenu" DOM event. Additionally, it provides two bits of sugar:
All that's required to use the "contextmenu" synthetic event is to add "event-contextmenu" to the use() statement.
YUI().use("event-contextmenu", function (Y) {
});
Here's a working example: The following button has a custom context menu. On Windows the context menu can be invoked by pressing either Menu or using Shift + F10, on the Mac use Shift + Ctrl + Alt + M.
Here's the code for the example:
YUI().use("event-contextmenu", "overlay", function (Y) {
var btn = Y.one("#btn-2"),
contextmenu;
function onContextmenu(e) {
if (!contextmenu) {
contextmenu = new Y.Overlay({
bodyContent: "<ul class=\"contextmenu\"><li>Option 1</li><li>Option 2</li><li>Option 3</li></ul>",
visible: false,
constrain: true
});
contextmenu.render(Y.one("body"));
}
contextmenu.set("xy", [e.pageX, e.pageY]);
contextmenu.show();
}
btn.on("contextmenu", onContextmenu);
});