不得不说,YUI的设计结构是蛮奇怪的。用惯了VCL就知道,操作PopupMenu是非常简单的事情,比如有popup(x.y)方法,直接可以指定弹出的目标。但是YUI有的信息,估计要狠看API和源码才能知道它设计在什么地方去了……
所以现在还是一个例子。例子说明一切问题。没有例子寸步难行。古人有云:吃饱没事干,上网博客逛……
原理:侦听目标DOM对象的单击事件 ,然后在鼠标位置弹出菜单。
下面是来自YUI Blog的完整代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Context Menu Example</title>

<!-- Standard reset and fonts -->
<link rel="stylesheet" type="text/css" href="../../build/reset/reset.css">
<link rel="stylesheet" type="text/css" href="../../build/fonts/fonts.css">

<!-- CSS for Menu -->
<link rel="stylesheet" type="text/css" href="../../build/menu/assets/menu.css">

<!-- Page-specific styles -->

<style type="text/css">...


#contextmenutarget {...}{
background-color:#ccc;
width:400px;
height:400px;
}
</style>

<!-- Namespace source file -->
<script type="text/javascript" src="../../build/yahoo/yahoo.js"></script>

<!-- Dependency source files -->
<script type="text/javascript" src="../../build/event/event.js"></script>
<script type="text/javascript" src="../../build/dom/dom.js"></script>

<!-- Container source file -->
<script type="text/javascript" src="../../build/container/container_core.js"></script>

<!-- Menu source file -->
<script type="text/javascript" src="../../build/menu/menu.js"></script>

<!-- Page-specific script -->

<script type="text/javascript">...

// "load" event handler for the "window" object


function onWindowLoad(p_oEvent) ...{

// Create the context menu


var oContextMenu = new YAHOO.widget.Menu("contextmenu1", ...{ visible: false } );


// Add Items
oContextMenu.addItem("Item One");
oContextMenu.addItem("Item Two");
oContextMenu.addItem("Item Three");


// Render the context menu

oContextMenu.render(document.body);


// "click" event handler for the "contextmenutarget" DIV


function onContextMenuTargetClick(p_oEvent) ...{
var nX = YAHOO.util.Event.getPageX(p_oEvent);
var nY = YAHOO.util.Event.getPageY(p_oEvent);

oContextMenu.cfg.applyConfig( ...{ x:nX, y:nY, visible:true } );
oContextMenu.cfg.fireQueue();
YAHOO.util.Event.stopEvent(p_oEvent);

var oTarget = YAHOO.util.Event.getTarget(p_oEvent);

alert(oTarget);
}

// Add a "click" event handler to the "contextmenutarget" DIV

YAHOO.util.Event.addListener("contextmenutarget", "click", onContextMenuTargetClick);


// "click" event handler for the "contextmenutarget" div


function onDocumentClick(p_oEvent) ...{
oContextMenu.hide();
}

// Add a "click" event handler to the document

YAHOO.util.Event.addListener(document, "click", onDocumentClick);

}


// Assign a "load" event handler to the window

YAHOO.util.Event.addListener(window, "load", onWindowLoad);
</script>

</head>
<body>
<div id="contextmenutarget">Click me for a "context menu."</div>
</body>
</html>
各位可能还要问,我不就一个转贴嘛,为什么还要写那么多废话。原因是……有些细节可以描述一下,大虾不入法眼,小虾自己拣。
注意这点:var oTarget = YAHOO.util.Event.getTarget(p_oEvent); 是获得Dom对象的关键。因为大部分的ContextMenu还要针对Dom对象(依赖于其上的属性、数据)进行下一步的操作,所以这个时候,只能把它变成一个全局的变量,然后在ContextMenu Item的各自点击中去访问这个对象。
接下来又是代码片断啦……
var oTarget = null ;


function onContextMenuTargetClick(p_oEvent) ...{
var nX = YAHOO.util.Event.getPageX(p_oEvent);
var nY = YAHOO.util.Event.getPageY(p_oEvent);

oContextMenu.cfg.applyConfig( ...{ x:nX, y:nY, visible:true } );
oContextMenu.cfg.fireQueue();
YAHOO.util.Event.stopEvent(p_oEvent);

oTarget = YAHOO.util.Event.getTarget(p_oEvent);

//alert(oTarget);
}

在菜单项的点击事件中,如下:

function onContextMenuClick(p_sType, p_aArgs, p_oMenu)...{

//如果右键弹出,下面代码可获得Dom对象
var p_oNode = this.contextEventTarget ;
//如果左键弹出,就要拿那个全局对象了……

if(p_oNode==null)...{
p_oNode= oTarget;
}

//p_oNode 现在就是Dom对象。
//玩命用吧。别浪费了

}