文/玄魂
目錄
node-webkit學習(4)Native UI API 之window.. 1
前言... 4
4.1 window api 概述... 5
4.2 獲取和建立視窗... 9
4.3 window物件屬性和方法... 11
4.3.1 Window.window.. 11
4.3.2 Window.x/Window.y. 13
4.3.3 Window.width/Window.height13
4.3.4 Window.title. 14
4.3.5 Window.menu. 16
4.3.6 Window.isFullscreen. 16
4.3.7 Window.isKioskMode. 16
4.3.8 Window.zoomLevel17
4.3.9 Window.moveTo(x, y)18
4.3.10 Window.moveBy(x, y)18
4.3.11 Window.resizeTo(width, height)18
4.3.12 Window.resizeBy(width, height)18
4.3.13 Window.focus()18
4.3.14 Window.blur()18
4.3.15 Window.show()18
4.3.16 Window.hide()19
4.3.17 Window.close([force])19
4.3.18 Window.reload()19
4.3.19 Window.reloadIgnoringCache()19
4.3.20 Window.maximize()19
4.3.21 Window.minimize()19
4.3.22 Window.restore()20
4.3.23 Window.enterFullscreen()20
4.3.24 Window.leaveFullscreen()20
4.3.25 Window.toggleFullscreen()20
4.3.26 Window.enterKioskMode()20
4.3.27 Window.leaveKioskMode()20
4.3.28 Window.toggleKioskMode()20
4.3.29 Window.showDevTools([id | iframe, headless])20
4.3.30 Window.closeDevTools()20
4.3.31 Window.isDevToolsOpen()21
4.3.32 Window.setMaximumSize(width, height)21
4.3.33 Window.setMinimumSize(width, height)21
4.3.34 Window.setResizable(Boolean resizable)21
4.3.35 Window.setAlwaysOnTop(Boolean top)21
4.3.36 Window.setPosition(String position)21
4.3.37 Window.setShowInTaskbar(Boolean show)21
4.3.38 Window.requestAttention(Boolean attention)21
4.3.39 Window.capturePage(callback [, image_format | config_object ])21
4.3.40 Window.cookies.*. 25
4.3.41 Window.eval(frame, script)25
4.4 window事件... 25
4.4.1 close. 25
4.4.2 closed. 25
4.4.3 loading. 26
4.4.4 loaded. 26
4.4.5 document-start27
4.4.6 document-end. 27
4.4.7 focus. 27
4.4.8 blur. 27
4.4.9 minimize. 27
4.4.10 restore. 27
4.4.11 maximize. 27
4.4.12 unmaximize. 27
4.4.13 move. 28
4.4.14 resize. 28
4.4.15 enter-fullscreen. 28
4.4.16 leave-fullscreen. 28
4.4.17 zoom.. 28
4.4.18 capturepagedone. 28
4.4.19 devtools-opened. 28
4.4.20 devtools-closed. 28
4.4.21 new-win-policy. 28
4.5 存在的問題... 29
4.6 小結... 29
幾個月前,要開發一個簡易的展示應用,要求支援離線播放(桌面應用)和線上播放(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。”
node-webkit版本 >= v0.3.0才支援window api。
Native GUI API 中的window是對DOM頁面的windows的一個封裝,擴充套件了DOM window的操作,同時可以接收各種事件。
每一個window都繼承 了node.js中的 EventEmitter 物件,你可以使用Window.on(...)的方式監聽native window的事件。
為了有一個整體上的認識,和上一篇文章(node-webkit學習(3)Native UI API概覽)一樣,我們先做一個小例子。之後會在這個示例的基礎上測試window api的各個屬性和方法。
先建立windowdemo.html和package.json檔案。
windowdemo.html檔案程式碼如下:
<html>
<head>
<title>windowdemo</title>
<metahttp-equiv="Content-Type"content="text/html; charset=utf-8"/>
</head>
<body>
<h1>window api 測試</h1>
<script>
var gui = require('nw.gui');
var win = gui.Window.get();
win.on('minimize', function () {
var element = document.createElement('div');
element.appendChild(document.createTextNode('視窗最小化'));
document.body.appendChild(element);
});
win.minimize();
var new_win = gui.Window.get(
window.open('http://ebook.xuanhun521.com')
);
new_win.on('focus', function () {
var element = document.createElement('div');
element.appendChild(document.createTextNode('新視窗被啟用'));
document.body.appendChild(element);
//Unlisten the minimize event
win.removeAllListeners('minimize');
});
</script>
</body>
</html>
package.json程式碼如下:
{
"name": "window-demo",
"main": "windowdemo.html",
"nodejs":true,
"width":100,
"height":200,
"window": {
"title": "windowdemo",
"toolbar": true,
"width": 800,
"height": 600,
"resizable":true,
"show_in_taskbar":true,
"frame":true,
"kiosk":false
},
"webkit":{
"plugin":true
}
}
現在我們簡單解釋下windowdemo.html,首先通過
var gui = require('nw.gui');
var win = gui.Window.get();
獲得當前視窗物件win,然後通過下面的程式碼定義了視窗最小化事件的處理函式。
win.on('minimize', function () {
var element = document.createElement('div');
element.appendChild(document.createTextNode('視窗最小化'));
document.body.appendChild(element);
});
當視窗最小化時,在當前DOM文件中新增一個div元素,文字內容為“視窗最小化”。
下面的程式碼示例瞭如何開啟一個新視窗。
通過類似的方式監聽新視窗的獲取焦點事件。
new_win.on('focus', function () {
var element = document.createElement('div');
element.appendChild(document.createTextNode('新視窗被啟用'));
document.body.appendChild(element);
//Unlisten the minimize event
});
上面的程式碼中通過removeAllListeners函式,移除了主視窗所有最小化事件的處理函式。
win.removeAllListeners('minimize');
執行程式,結果如下:
基本的獲取、新建視窗,建立和移除事件監聽函式的方式,現在都有了整體上的認識,下面對window的屬性和方法逐一介紹。
鄙視不標明出處的轉載,更多相關內容,歡迎訪問玄魂的部落格(www.xuanhun521.com)
獲取和建立新的window都是使用get方法,在上面的示例中,已經演示的很清楚,無參的get方法獲取當前視窗物件。
var win = gui.Window.get();
向get方法傳入一個DOM window物件,會開啟新的視窗。
var new_win = gui.Window.get(
window.open('https://github.com')
);
獲取新視窗物件的另一種方法是,使用nw.gui.Window.open方法。
var win = gui.Window.open('http://ebook.xuanhun521.com', {
position: 'center',
width: 901,
height: 127
});
該方法傳入一個url,可選的配置引數,新窗體會載入url。在最新版本的node-webkit,預設情況下新開啟的視窗是沒有被啟用的(未獲取焦點),如果想預設獲取焦點,可以在在配置中設定“focus”屬性為true,如下:
var win = gui.Window.open('http://ebook.xuanhun521.com', {
position: 'center',
width: 901,
height: 127,
focus:true
});
修改windowdemo.html如下,使用gui.Window.open的方式開啟新視窗。
<html>
<head>
<title>windowdemo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body >
<h1>window api 測試</h1>
<script>
var gui = require('nw.gui');
var win = gui.Window.get();
win.on('minimize', function () {
var element = document.createElement('div');
element.appendChild(document.createTextNode('視窗最小化'));
document.body.appendChild(element);
});
win.minimize();
//var new_win = gui.Window.get(
// window.open('http://ebook.xuanhun521.com')
//);
var new_win = gui.Window.open('http://ebook.xuanhun521.com', {
position: 'center',
width: 901,
height: 127,
focus: true
});
new_win.on('focus', function () {
var element = document.createElement('div');
element.appendChild(document.createTextNode('新視窗被啟用'));
document.body.appendChild(element);
//Unlisten the minimize event
win.removeAllListeners('minimize');
});
</script>
</body>
</html>
Window.window屬性獲取的是當前DOM文件中的window物件。
修改windowdemo.html內容如下:
<html>
<head>
<title>windowdemo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body >
<h1>window api 測試</h1>
<script>
var gui = require('nw.gui');
var win = gui.Window.get();
if (win.window == window)//比較是否為DOM window
{
var element = document.createElement('div');
element.appendChild(document.createTextNode('Window.window 和DOM window物件相同'));
document.body.appendChild(element);
}
</script>
</body>
</html>
執行結果如下:
獲取或者設定當前視窗在當前顯示螢幕內的x/y偏移。
下面我們修改windowdemo.html,使其顯示後移動到螢幕的左上角。
var gui = require('nw.gui');
var win = gui.Window.get();
win.x = 0;
win.y = 0;
獲取或設定當前視窗的大小。
修改windowdemo.html的script如下:
<script>
var gui = require('nw.gui');
var win = gui.Window.get();
var windowWidth = win.width;
var windowHeight = win.height;
if (win.window == window)
{
var element = document.createElement('div');
element.appendChild(document.createTextNode('nativeWidth:' + windowWidth ));
document.body.appendChild(element);
}
</script>
執行結果如下:
獲取或者窗體的標題。
到目前為止,有兩個地方可以設定起始窗體的標題,package.json和DOM頁面的title。下面我們通過Window.title屬性先獲取再修改視窗標題。
修改後的頁面內容為:
<html>
<head>
<title>windowdemo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body >
<h1>window api 測試</h1>
<input type="button" value="修改視窗標題" id="btn_ChangeTitle" onclick="changeTitle()"/>
<script>
var gui = require('nw.gui');
var win = gui.Window.get();
var windowWidth = win.width;
var windowHeight = win.height;
if (win.window == window)
{
var element = document.createElement('div');
element.appendChild(document.createTextNode('nativeWidth:' + windowWidth ));
document.body.appendChild(element);
}
function changeTitle()
{
win.title = "新標題";
}
</script>
</body>
</html>
程式啟動時介面如下:
點選“修改視窗標題”按鈕之後:
獲取或設定window的menubar。會在menu一節中詳細介紹。
獲取或設定是否以全屏模式展現窗體。如果程式啟動時就全屏顯示,需要在package.json中配置(參考:http://www.xuanhun521.com/Blog/2014/4/10/node-webkit%E5%AD%A6%E4%B9%A02%E5%9F%BA%E6%9C%AC%E7%BB%93%E6%9E%84%E5%92%8C%E9%85%8D%E7%BD%AE)
獲取或設定是否啟用KioskMode。
獲取 或者設定窗體內頁面的zoom值。正值代表zoom in,負值代表zoom out。
如在之前的指令碼中新增
win.zoomLevel = 50;
顯示效果如下:
如果設定
win.zoomLevel = -50;
效果如下:
移動視窗到指定座標點。
以當前位置為0點,移動x,y距離。
重新設定視窗大小。
以當前視窗大小為基準,重新增加指定值到視窗的寬高。
使視窗獲取焦點。
使視窗失去焦點
顯示隱藏的視窗。在某些平臺上,show方法並不會使視窗獲取焦點,如果你想在視窗顯示的同時使其獲取焦點,需要呼叫focus方法。
show(false)和Window.hide()方法效果一樣。
隱藏視窗。
關閉窗體。可以通過監聽close事件,阻止視窗關閉。但是如果force=true,將會忽略close事件的監聽程式。
一般情況下,我們會在程式中先監聽close事件,在事件處理函式中做一些基本工作再關閉視窗。如:
win.on('close', function() {
this.hide(); // Pretend to be closed already
console.log("We're closing...");
this.close(true);
});
win.close();
重新載入視窗。
重新載入窗體,強制重新整理快取。
是視窗最大化
最小化視窗。
恢復視窗到上一狀態。
使視窗進入全屏模式。這和html5的FullScreen API不同,html5可以使頁面的一部分全屏,該方法只能使整個視窗全屏。
退出全屏模式。
切換全屏模式。
進入Kiosk模式。Kiosk模式使應用全屏,並且阻止使用者退出。所以在該模式下必須提供退出Kiosk模式的途徑。
退出Kiosk模式。
切換Kiosk模式。
在視窗中開啟開發者工具。
詳情 參見:https://github.com/rogerwang/node-webkit/wiki/Devtools-jail-feature
關閉開發者工具。
返回開發者工具是否被開啟的狀態資訊。
設定視窗的最大值。
設定視窗的最小值。
設定視窗是否可以被重置大小。
設定視窗是否總在最前端。
移動窗體到指定位置。目前只有“center”支援所有平臺,將視窗移動到螢幕中央。
設定是否允許在工作列顯示圖示。
是否需要身份驗證。
對視窗內的內容作截圖。我們通過一個例項來理解它的用法。
新建html:
<html>
<head>
<title>windowdemo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body style="background: #333">
<h1>window 測試</h1>
<script>
var gui = require('nw.gui');
var win = gui.Window.get();
function takeSnapshot() {
win.capturePage(function (img) {
var base64Data = img.replace(/^data:image\/(png|jpg|jpeg);base64,/, "");
require("fs").writeFile("out.png", base64Data, 'base64', function (err) {
console.log(err);
});
}, 'png');
}
</script>
<div style="background: #123; width:100px; height:100px; border:1px solid #000">
</div>
<button onclick="takeSnapshot()">截圖</button>
</body>
</html>
在上面的程式碼中,呼叫win.capturePage進行截圖,截圖的結果會傳入到回撥函式中,傳入的資料是base64字串,程式通過require("fs").writeFile方法將圖片輸出。
執行結果如下:
從node-webkit v0.9.3開始,可以通過配置引數的方式進行截圖了,使用方法如下:
// png as base64string
win.capturePage(function(base64string){
// do something with the base64string
}, { format : 'png', datatype : 'raw'} );
// png as node buffer
win.capturePage(function(buffer){
// do something with the buffer
}, { format : 'png', datatype : 'buffer'} );
配置項可用值參考:
{
format : "[jpeg|png]",
datatype : "[raw|buffer|datauri]"
}
預設情況下,format值為jpeg,datatype為datauri。
包含一些列處理cookie的方法。這些api的定義方式和chrome擴充套件相同。node-webkit支援get, getAll, remove 和 set 方法; onChanged 事件 (該事件支援支援 both addListener 和 removeListener 方法)。
和CookieStore有關的擴充套件api不被支援,因為node-webkit只有一個全域性的cookie儲存。
在目標window或者iframe中執行javascript程式碼段。script引數是要執行的javascript程式碼。
鄙視不標明出處的轉載,更多相關內容,歡迎訪問玄魂的部落格(www.xuanhun521.com)
本節介紹的事件,都可以通過Window.on()方法進行監聽,更多接收事件相關內容參考node.js文件, EventEmitter。
關閉視窗事件。參考上文window.close()方法。
視窗關閉完畢事件。正常情況下在同一窗體內是無法監聽此事件的,以為視窗已經關閉,所有javascript 物件都被釋放掉了。
但是我們可以通過在另一視窗,監聽被關閉視窗的已關閉事件。如:
<script>
var gui = require('nw.gui');
//var new_win = gui.Window.get(
// window.open('http://ebook.xuanhun521.com')
//);
var new_win = gui.Window.open('http://ebook.xuanhun521.com', {
position: 'center',
width: 901,
height: 127,
focus: true
});
new_win.on('closed', function () {
var element = document.createElement('div');
element.appendChild(document.createTextNode('新視窗已經關閉'));
document.body.appendChild(element);
});
</script>
在當前窗體監聽新建窗體的已關閉事件,關閉新視窗後的顯示結果:
視窗正在初始化時的事件。
該事件只能在重新整理視窗或者在其他視窗中監聽。
視窗初始化完畢。
function (frame) {}
窗體中的document物件或者iframe中的css檔案都載入完畢,DOM元素還未開始渲染,javascript程式碼還未執行,觸發此事件。
監聽事件的函式會接收一個frame引數,值為具體的iframe物件或者為null。
讀者可同時參考node webkit學習(2)基本結構和配置中的inject-js-start
function (frame) {}
文件載入完畢觸發的事件。
獲取焦點的事件。
失去焦點的事件。
視窗最小化事件。
當視窗從最小化重置到上一狀態時觸發的事件。
視窗最大化事件。
視窗從最大化狀態重置到之前的狀態時觸發的事件。
視窗被移動後引發的事件。
事件處理函式應該接收兩個引數(x,y),是視窗的新位置。
窗體大小被重置時觸發的事件。
事件監聽的回撥函式接收兩個引數(width,height),視窗的新大小。
視窗進入全屏模式時觸發的事件。
退出全屏模式時觸發的事件。
當窗體中文件發生zooming時觸發的事件,帶有zoomlevel引數,參見上文的window.zoom屬性。
截圖完畢觸發的事件,事件的傳遞引數參考上文Window.capturePage函式的回撥函式的引數定義。
開發者工具被開啟觸發的事件。
事件的回撥函式接收一個url引數,是開啟開發者工具的視窗地址。
開發者工具被關閉時觸發的事件。
當一個新視窗被從當前視窗開啟,或者開啟一個iframe時觸發該事件。
function (frame, url, policy) {}
· frame 發起請求的子iframe,如果從頂層視窗中發起的請求,該值為null
· url 請求的地址
· policy 帶有以下方法的物件
o ignore() : 忽略請求。
o forceCurrent() :強制在同一frame中開啟連結
o forceDownload() : 強制連結被下載或者在其他應用中開啟
o forceNewWindow() : 強制在新視窗中開啟連結
o forceNewPopup() : 強制在新的 popup window中開啟連結
在linux下, setMaximumSize()/setMinimumSize()
和 setResizable()
方法不能被同時使用。
本文內容主要參考node-webkit的官方英文文件(https://github.com/rogerwang/node-webkit/wiki/Window)。
下一篇文章,介紹Frameless window。
鄙視不標明出處的轉載,更多相關內容,歡迎訪問玄魂的部落格(www.xuanhun521.com)
更多相關內容,歡迎訪問玄魂的部落格(更多node-webkit相關內容 http://www.xuanhun521.com/Blog/Tag/node-webkit)
ps:nw.js,electron交流群 313717550