与 NativeMenu 的用户交互是事件驱动的。当用户选择菜单项或打开菜单或子菜单时,NativeMenuItem 对象将调度一个事件。使用通过 MenuBuilder 框架创建的 NativeMenu 对象,可以将事件侦听器注册到各个 NativeMenuItem 对象或 NativeMenu。订阅和响应这些事件时,就好像您已经以手动方式而不是使用 MenuBuilder 框架创建了 NativeMenu 和 NativeMenuItem 对象。有关详细信息,请参阅
菜单的事件
。
MenuBuilder 框架补充了标准事件处理过程,从而使您可以在菜单数据源中为菜单项指定
select
事件处理函数。如果在菜单项数据源中指定
onSelect
字段,则当用户选择菜单项时,将调用所指定的函数。例如,假设以下 XML 节点包含在使用 MenuBuilder 框架加载的数据源中。当选择菜单项时,将调用名为
doSave()
的函数:
<menuitem label="Save" onSelect="doSave"/>
用于 XML 数据源时,
onSelect
字段是 String。使用 JSON 数组时,此字段可以是有函数名称的 String。此外,仅对 JSON 数组,该字段还可以是对作为对象的函数的变量引用。但是,如果 JSON 数组使用 Function 变量引用,则必须在发生
onload
事件处理函数或 JavaScript 安全违规之前或在此期间创建菜单。在所有情况中,必须在全局作用域内定义所指定的函数。
调用所指定的函数时,运行时会向它传递两个参数。第一个参数是由
select
事件调度的事件对象。它是 Event 类的实例。传递给此函数的第二个参数是匿名对象,其中包含用于创建菜单项的数据。此对象有以下属性。每个属性的值均与原始数据结构中的值匹配,如果未在原始数据结构中设置该属性,则其值为
null
:
以下示例用于实验 NativeMenu 事件。该示例包括两个菜单。窗口和应用程序菜单使用 XML 数据源创建。由
<ul>
和
<li>
元素所表示的项目列表的上下文菜单使用 JSON 数组数据源创建。当用户选择菜单项时,屏幕上的文本区域将显示有关每个事件的信息。
以下代码是应用程序的源代码:
<html>
<head>
<title>Menu event handling example</title>
<script type="text/javascript" src="AIRAliases.js"></script>
<script type="text/javascript" src="AIRMenuBuilder.js"></script>
<script type="text/javascript" src="printObject.js"></script>
<script type="text/javascript">
function fileMenuCommand(event, data) {
print("fileMenuCommand", event, data);
}
function editMenuCommand(event, data) {
print("editMenuCommand", event, data);
}
function moveItemUp(event, data) {
print("moveItemUp", event, data);
}
function moveItemDown(event, data) {
print("moveItemDown", event, data);
}
function print(command, event, data) {
var result = "";
result += "<h1>Command: " + command + '</h1>';
result += "<p>" + printObject(event) + "</p>";
result += "<p>Data:</p>";
result += "<ul>";
for (var s in data) {
result += "<li>" + s + ": " + printObject(data[s]) + "</li>";
}
result += "</ul>";
var o = document.getElementById("output");
o.innerHTML = result;
}
</script>
<style type="text/css">
#contextList {
position: absolute; left: 0; top: 25px; bottom: 0; width: 100px;
background: #eeeeee;
}
#output {
position: absolute; left: 125px; top: 25px; right: 0; bottom: 0;
}
</style>
</head>
<body>
<div id="contextList">
<ul>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
</ul>
</div>
<div id="output">
Choose menu commands. Information about the events displays here.
</div>
<script type="text/javascript">
var mainMenu = air.ui.Menu.createFromXML("mainMenu.xml");
air.ui.Menu.setAsMenu(mainMenu);
var listContextMenu = air.ui.Menu.createFromJSON("listContextMenu.js");
air.ui.Menu.setAsContextMenu(listContextMenu, "contextList")
// clear the default context menu
air.ui.Menu.setAsContextMenu(null);
</script>
</body>|
</html>
以下代码是主菜单(“mainMenu.xml”)的数据源:
<?xml version="1.0" encoding="utf-8" ?>
<root>
<menuitem label="File">
<menuitem label="New" keyEquivalent="n" onSelect="fileMenuCommand"/>
<menuitem label="Open" keyEquivalent="o" onSelect="fileMenuCommand"/>
<menuitem label="Save" keyEquivalent="s" onSelect="fileMenuCommand"/>
<menuitem label="Save As..." keyEquivalent="S" onSelect="fileMenuCommand"/>
<menuitem label="Close" keyEquivalent="w" onSelect="fileMenuCommand"/>
</menuitem>
<menuitem label="Edit">
<menuitem label="Cut" keyEquivalent="x" onSelect="editMenuCommand"/>
<menuitem label="Copy" keyEquivalent="c" onSelect="editMenuCommand"/>
<menuitem label="Paste" keyEquivalent="v" onSelect="editMenuCommand"/>
</menuitem>
</root>
以下代码是上下文菜单(“listContextMenu.js”)的数据源;
[
{label: "Move Item Up", onSelect: "moveItemUp"},
{label: "Move Item Down", onSelect: "moveItemDown"}
]
以下代码包含 printObject.js 文件中的代码。在本例中,该文件包括
printObject()
函数,该函数由应用程序使用,但它不影响菜单的操作。
function printObject(obj) {
if (!obj) {
if (typeof obj == "undefined") { return "[undefined]"; };
if (typeof obj == "object") { return "[null]"; };
return "[false]";
} else {
if (typeof obj == "boolean") { return "[true]"; };
if (typeof obj == "object") {
if (typeof obj.length == "number") {
var ret = [];
for (var i=0; i<obj.length; i++) {
ret.push(printObject(obj[i]));
}
return ["[", ret.join(", "), "]"].join(" ");
} else {
var ret = [];
var hadChildren = false;
for (var k in obj) {
hadChildren = true;
ret.push ([k, " => ", printObject(obj[k])]);
}
if (hadChildren) {
return ["{\n", ret.join(",\n"), "\n}"].join("");
}
}
}
if (typeof obj == "function") { return "[Function]"; }
return String(obj);
}
}