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); });