文/玄魂
目錄
node-webkit教程(6)Native UI API 之Menu(菜單)
前言
6.1 Menu 概述
6.2 menu api
6.2.1 new Menu([option])
6.2.2 Menu.items
6.2.3 Menu.items.length
6.2.4 Menu.items[i]
6.2.5 Menu.append(MenuItem item)
6.2.6 Menu.insert(MenuItem item, int i)
6.2.7 Menu.remove(MenuItem item)
6.2.8 Menu.removeAt(int i)
6.2.9 Menu.item[x].click
6.2.10 Menu.popup(int x, int y)
6.3 創建右鍵菜單
6.4 MenuItem
6.4.1 new MenuItem(option)
6.4.2 MenuItem.type
6.4.3 MenuItem.label
6.4.4 MenuItem.icon
6.4.5 MenuItem.tooltip
6.4.6 MenuItem.checked
6.4.7 MenuItem.enabled
6.4.8 MenuItem.submenu
6.4.9 MenuItem.click
6.6 小結
幾個月前,要開發一個簡易的展示應用,要求支持離線播放(桌面應用)和在線播放(web應用)。
當時第一想到的是flex,同一套代碼(或者只需少量的更改)就可以同時運行在桌面和瀏覽器上。由於很多展現效果要全新開發,我想到了impress.js(https://github.com/bartaz/impress.js/)。如果選擇impress.js,就意味着要將html5作為桌面應用,當時想到要封裝webkit,但是本人對這方面也不是很熟悉,時間也很有限,就又沿着這個方向搜索,找到了node-webkit(https://github.com/rogerwang/node-webkit)。
node-webkit解決了我通過html和js來編寫桌面應用的難題。
至於node-webkit的定義,按照作者的說法:
“ 基於node.js和chromium的應用程序實時運行環境,可運行通過HTML(5)、CSS(3)、Javascript來編寫的本地應用程序。node.js和webkit的結合體,webkit提供DOM操作,node.js提供本地化操作;且將二者的context完全整合,可在HTML代碼中直接使用node.js的API。”
Menu API 提供的是本地化的窗口菜單,即windows下常說的菜單欄,定義的菜單顯示在本地化(native)window上,而不是屬於DOM文檔。參考:node-webkit學習(4)Native UI API 之window(http://www.xuanhun521.com/Blog/2014/4/14/node-webkit%E5%AD%A6%E4%B9%A04native-ui-api-%E4%B9%8Bwindow)
Menu分為兩種,window菜單和上下文(右鍵)菜單(context menu)。
創建menu對象使用構造函數Menu([option]),如:
// Load native UI library
var gui = require('nw.gui');
// Create an empty menu
var menu = new gui.Menu();
不帶參數構造的menu屬於context menu,如果想創建window menu,使用如下方式:
var your_menu = new gui.Menu({ type: 'menubar' });
將window menu直接賦值給window 對象的menu屬性即可生效。
gui.Window.get().menu = your_menu;
創建menuDemo.html和package.json。menuDemo.html代碼如下:
<html>
<head>
<title>menuDemo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body >
<h1>menu api 測試</h1>
<script>
// Load native UI library
var gui = require('nw.gui');
var win = gui.Window.get();
//創建window menu
var windowMenu = new gui.Menu({ type: 'menubar' });
var windowSubmenu = new gui.Menu();
var subMenuItem = new gui.MenuItem({ label: '子菜單項' });
windowSubmenu.append(subMenuItem);
windowMenu.append(
new gui.MenuItem({ label: '子菜單', submenu: windowSubmenu })
);
win.menu = windowMenu;
// Create an empty menu
var menu = new gui.Menu();
// Add some items
menu.append(new gui.MenuItem({ label: 'Item A' }));
menu.append(new gui.MenuItem({ label: 'Item B' }));
menu.append(new gui.MenuItem({ type: 'separator' }));
menu.append(new gui.MenuItem({ label: 'Item C' }));
// Remove one item
menu.removeAt(1);
// Popup as context menu
menu.popup(10, 10);
// Iterate menu's items
for (var i = 0; i < menu.items.length; ++i) {
var element = document.createElement('div');
element.appendChild(document.createTextNode(menu.items[i].label));
document.body.appendChild(element);
}
</script>
</body>
</html>
package.json文件內容如下:
{
"name": "menu-demo",
"main": "menuDemo.html",
"nodejs":true,
"width":100,
"height":200,
"window": {
"title": "MenuDemo",
"toolbar": true,
"width": 800,
"height": 600,
"resizable":true,
"show_in_taskbar":true,
"frame":true,
"kiosk":false
},
"webkit":{
"plugin":true
}
}
運行結果如下:
鄙視不標明出處的轉載,更多相關內容,歡迎訪問玄魂的博客(www.xuanhun521.com)
構造函數,見上文。
獲取該Menu下所有的MenuItem對象,返回結果為數組。上文中的例子,有這樣的代碼:
for (var i = 0; i < menu.items.length; ++i) {
var element = document.createElement('div');
element.appendChild(document.createTextNode(menu.items[i].label));
document.body.appendChild(element);
}
上面的代碼通過menu.items獲取所有menuitem對象,遍歷輸出label。這里需要注意的是,並不是所有的menuitem都有label屬性。
menuitem的個數。參加上文demo。
通過索引返回一個menuitem對象。
向當前菜單中添加一個menuitem對象,該對象在整個menuitem集合的尾部。
在menuitem集合的指定位置插入一個menuitem對象。
從menuitem集合中移除一個menuitem對象。
刪除menuitem集合中指定位置的menuitem對象。
設置menuitem集合中指定位置的menuitem對象的click事件,在menuDemo.html中添加如下代碼:
menu.items[0].click = function() {
var element = document.createElement('div');
element.appendChild(document.createTextNode(‘我被點擊了’));
document.body.appendChild(element);
};
結果如下:
點擊前
點擊后
在當前窗口的指定位置彈窗菜單。示例代碼見上文。
創建右鍵菜單,需要在頁面監聽contextmenu
事件,然后控制彈出菜單。修改之前的菜單彈出代碼:
document.body.addEventListener('contextmenu', function (ev) {
ev.preventDefault();
menu.popup(10, 10);
return false;
});
啟動時頁面如下:
單擊右鍵后,界面顯示菜單:
鄙視不標明出處的轉載,更多相關內容,歡迎訪問玄魂的博客(www.xuanhun521.com)
從上面的敘述中,我們已經知道,menu和menuitem的一起組合,才能最終組成界面上的菜單。到目前為止,我們已經基本了解了menuitem的基本使用方法,下面根據api文檔,詳細介紹屬性、方法和事件。
初始化一個Menuitem對象,其中option是一個對象,包含label, icon, tooltip, type, click, checked, enabled 和 submenu這些字段。這些字段都具有自己的屬性,下面分別敘述。
獲取一個menuitem的類別信息,到目前為止有三類menuitem,分別為separator, checkbox 和normal。
normal和separator類型的menuitem我們都已經在上面的示例中見到,下面我們添加一個checkbox類型的menuitem。
menu.append(new gui.MenuItem({ label: '請選擇',type:'checkbox' }));
結果如下:
需要注意的是,type字段只能在初始化時設定,在運行時是不能修改menuitem的類型的。
獲取或設置menuitem的label值,目前只支持純文本。
菜單的圖標,支持app內部的相對路徑和系統路徑。sepatater類型的menuitem不支持icon屬性。只支持png格式的圖片。
修改sumMenuItem,為它添加icon:
var subMenuItem = new gui.MenuItem({ label: '子菜單項', icon: '2655716405282662783.png' });
效果如下:
或者或者設置tooltip字段。所謂tooltip就是當鼠標滑動到菜單上顯示的文本信息,類似於DOM元素中的title。
下面我們繼續修改subMenuItem,為其添加tooltip:
var subMenuItem = new gui.MenuItem({ label: '子菜單項', icon: '2655716405282662783.png',tooltip:'我是帥氣的子菜單' });
很不幸,在我的windows 7機器上,tooltip無法顯示。在ubuntu上,menubar是顯示在全局菜單上,看起來有點怪異:
獲取或設置menuitem是否被選中。
獲取或者menuitem的enaled屬性,enabled設置為false的menuitem不可被選中。
獲取或者是子菜單。可以參考本文的示例。
獲取或設置click事件的回調函數。
本文內容主要參考node-webkit的官方英文文檔(https://github.com/rogerwang/node-webkit/wiki/Menu,https://github.com/rogerwang/node-webkit/wiki/MenuItem,https://github.com/rogerwang/node-webkit/wiki/Window-menu)。
下一篇文章,介紹Platform Services。
鄙視不標明出處的轉載,更多相關內容,歡迎訪問玄魂的博客(www.xuanhun521.com)
更多相關內容,歡迎訪問玄魂的博客(更多node-webkit相關內容 http://www.xuanhun521.com/Blog/Tag/node-webkit)
ps:nw.js,electron交流群 313717550