文/玄魂javascript
目錄css
node-webkit學習(4)Native UI API 之windowhtml
前言前端
4.1 window api 概述html5
4.2 獲取和建立窗口java
4.3 window對象屬性和方法node
4.3.1 Window.windowlinux
4.3.2 Window.x/Window.yios
4.3.3 Window.width/Window.heightgit
4.3.4 Window.title
4.3.5 Window.menu
4.3.6 Window.isFullscreen
4.3.7 Window.isKioskMode
4.3.8 Window.zoomLevel
4.3.9 Window.moveTo(x, y)
4.3.10 Window.moveBy(x, y)
4.3.11 Window.resizeTo(width, height)
4.3.12 Window.resizeBy(width, height)
4.3.13 Window.focus()
4.3.14 Window.blur()
4.3.15 Window.show()
4.3.16 Window.hide()
4.3.17 Window.close([force])
4.3.18 Window.reload()
4.3.19 Window.reloadIgnoringCache()
4.3.20 Window.maximize()
4.3.21 Window.minimize()
4.3.22 Window.restore()
4.3.23 Window.enterFullscreen()
4.3.24 Window.leaveFullscreen()
4.3.25 Window.toggleFullscreen()
4.3.26 Window.enterKioskMode()
4.3.27 Window.leaveKioskMode()
4.3.28 Window.toggleKioskMode()
4.3.29 Window.showDevTools([id | iframe, headless])
4.3.30 Window.closeDevTools()
4.3.31 Window.isDevToolsOpen()
4.3.32 Window.setMaximumSize(width, height)
4.3.33 Window.setMinimumSize(width, height)
4.3.34 Window.setResizable(Boolean resizable)
4.3.35 Window.setAlwaysOnTop(Boolean top)
4.3.36 Window.setPosition(String position)
4.3.37 Window.setShowInTaskbar(Boolean show)
4.3.38 Window.requestAttention(Boolean attention)
4.3.39 Window.capturePage(callback [, image_format | config_object ])
4.3.40 Window.cookies.*
4.3.41 Window.eval(frame, script)
4.4 window事件
4.4.1 close
4.4.2 closed
4.4.3 loading
4.4.4 loaded
4.4.5 document-start
4.4.6 document-end
4.4.7 focus
4.4.8 blur
4.4.9 minimize
4.4.10 restore
4.4.11 maximize
4.4.12 unmaximize
4.4.13 move
4.4.14 resize
4.4.15 enter-fullscreen
4.4.16 leave-fullscreen
4.4.17 zoom
4.4.18 capturepagedone
4.4.19 devtools-opened
4.4.20 devtools-closed
4.4.21 new-win-policy
4.5 存在的問題
幾個月前,要開發一個簡易的展現應用,要求支持離線播放(桌面應用)和在線播放(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。
ps:nw.js,electron交流羣 313717550