Slide 1

Slide 1 text

精通 JavaScript 作 Windows Store App 開發 DEV308 蔡秉諺 Vexed 中華電信 Xuite

Slide 2

Slide 2 text

課程簡介 Windows Store App ⽀支援以原先⽤用於網⾴頁前端 開發的 HTML/CSS/JavaScript 技術來進⾏行 app 的開發,這使得原先做網⾴頁開發的開發 ⼈人員得以使⽤用既有的知識及技能來開發 Windows 8 Apps。
 
 本課程將會介紹在使⽤用 JavaScript 開發 Windows 8 Apps 時的細節,以及瞭解如何運 ⽤用開發環境提供的 WinJS 函式庫來開發 Windows 8 Apps。

Slide 3

Slide 3 text

微軟跟你說 ⽤用 JavaScript 開發 Windows Store App
 
 和開發網⾴頁前端很像 很像 !== ⼀一樣

Slide 4

Slide 4 text

不⼀一樣 顧名思義
 
 可以上 Windows Store 可以碰到系統底層 可以離線操作

Slide 5

Slide 5 text

不⼀一樣 多 Windows 、 WinJS 、 MSApp 物件 少不適合 App 環境函式 適應 App 環境⾏行為改變 Cross-Domain AJAX

Slide 6

Slide 6 text

Windows 物件 不是 window 物件 Windows Runtime API (WinRT API) C++ C# VB JavaScript 共通

Slide 7

Slide 7 text

Windows 物件 不夠⽤用、⾃自⼰己寫 WinRT Component C++ C# VB

Slide 8

Slide 8 text

WinJS 物件 Windows Library for JavaScript 100% JavaScript 寫成 跟 jQuery YUI ⼀一樣 原始碼可以看、不能改

Slide 9

Slide 9 text

WinJS 物件 看原始碼、⽐比看⽂文件快 base.js WinJS
 ui.js WinJS.UI 鎖 註解 搜尋

Slide 10

Slide 10 text

不⽤用 WinJS
 能寫 Windows Store App 嗎? 不⽤用 jQuery 能寫網⾴頁嗎? 能、但⿇麻煩 WinJS 存在意義 拉近 Windows 物件與網⾴頁前端開發距離

Slide 11

Slide 11 text

WinJS 能在
 Windows Store App 外⽤用嗎? base.js ui.js 開頭註解 This library is supported for use in Windows Store apps only. 原始碼找 hasWinRT 未使⽤用 Windows 物件分出 為了 web context

Slide 12

Slide 12 text

少不適合 App 環境函式 不可開新視窗 無 open、moveBy、moveTo、resizeBy、resizeTo window.close() 中⽌止 App 、例外使⽤用 無 alert、comfirm、prompt Windows.UI.Popups.MessageDialog 替代 改變動線

Slide 13

Slide 13 text

替代 alert var md = new Windows.UI.Popups.MessageDialog('Hi');
 md.showAsync().then(function() { 
 // ...
 }); 關閉

Slide 14

Slide 14 text

替代 confirm var md = new Windows.UI.Popups.MessageDialog('Are you OK?');
 
 md.commands.append(new Windows.UI.Popups.UICommand('Yes'));
 md.commands.append(new Windows.UI.Popups.UICommand('No'));
 
 md.showAsync().then(function (cmd) {
 console.log(cmd.label);
 });

Slide 15

Slide 15 text

替代 prompt 無直接⽅方案 改變動線 選項明確 Windows.UI.Popups.MessageDialog 同 confirm Flyout 控制項 無 Block UI

Slide 16

Slide 16 text

Slide 19

Slide 19 text

外部連結 Bing 跳離 App 、 Modern IE 開啟

Slide 21

Slide 21 text

innerHTML、document.write ...
 安全機制 elm.innerHTML = '

!

'; JavaScript 錯誤 elm.innerHTML = ''; JavaScript 錯誤 elm.innerHTML = toStaticHTML('…'); Safe

Slide 22

Slide 22 text

限制載⼊入外部 JavaScript JavaScript 錯誤 檔案下載、加⼊入 App 內

Slide 23

Slide 23 text

Cross-Domain AJAX XMLHttpRequest Cross-Domain WinJS.xhr XMLHttpRequest Cross-Domain WinJS.xhr({ url : 'a.txt' }).then(function() {
 // …
 }); App 內檔案

Slide 24

Slide 24 text

MSApp 物件 額外審查? 都不是好東⻄西? WinJS 原始碼找 Unsafe MSApp.execUnsafeLocalFunction

Slide 25

Slide 25 text

MSApp.execUnsafeLocalFunction innerHTML、document.write ... 安全機制 elm.innerHTML = '

!

'; JavaScript 錯誤 MSApp.execUnsafeLocalFunction(function() {
 elm.innerHTML = '

!';
 }); Pass

Slide 26

Slide 26 text

App 中顯⽰示外部網⾴頁 Bing 外部連結、跳離 App 、 Modern IE 開啟 iframe 內 local context、外 web context iframe 內外 local context 外部網⾴頁 App 內網⾴頁

Slide 27

Slide 27 text

web context 與 Windows Store App 外幾乎相同 無 Windows 物件 WinJS 部分可⽤用 無 innerHTML、document.write ... 安全機制 不限制載⼊入外部 JavaScript AJAX 不可 Cross-Domain WinJS 原始碼找 hasWinRT

Slide 28

Slide 28 text

web context App 內網⾴頁 web context 載⼊入 local context 、 web context 溝通 HTML5 postMessage()

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

Windows Store App ⽤用 jQuery JavaScript 錯誤 限制載⼊入外部 JavaScript 檔案下載、加⼊入 App 內

Slide 31

Slide 31 text

Windows Store App ⽤用 jQuery App 執⾏行 3 個 JavaScript 錯誤 jQuery 初始時觸犯 innerHTML、document.write ... 安全機制 原始碼找 改 jQuery.support = (function() { ... })(); jQuery.support = MSApp.execUnsafeLocalFunction(function() { ... }

Slide 32

Slide 32 text

Windows Store App ⽤用 jQuery 待續 …

Slide 33

Slide 33 text

Windows Store App ⽤用
 Google Maps JavaScript API 限制載⼊入外部 JavaScript 無法檔案下載、加⼊入 App 內 Google Map 放 map.html 裡 web context 載⼊入

Slide 34

Slide 34 text

ECMAScript 5 Windows Store App 、 IE10 ⽀支援 WinJS 原始碼 不普及原因 IE8 + Windows XP ECMAScript 5 compatibility table 兇

Slide 35

Slide 35 text

ECMAScript 5 可 JavaScript 模擬 Array.prototype.forEach Object.keys … 需瀏覽器底層⽀支援 Object getter setter Object.defineProperty Strict Mode …

Slide 36

Slide 36 text

Object getter setter on 、 off 屬性 只可讀、不可寫 var strings = {
 get on() { return WinJS.Resources._getWinJSString("ui/on").value; },
 get off() { return WinJS.Resources._getWinJSString("ui/off").value; },
 }; 沒有 JavaScript 錯誤 var v = 1,
 o = { get p() { return v; },
 set p(x) { v += x; } }; 
 o.p = 2;
 console.log(o.p); // 3

Slide 37

Slide 37 text

Object.defineProperty configurable 、 writable 、 enumerable 以前存在、看不到、碰不到 Object.defineProperty(element, "winBindingToken", {
 configurable: false,
 writable: false,
 enumerable: false,
 value: bindingToken
 }
 );

Slide 38

Slide 38 text

Strict Mode "use strict"; Visual Studio 2012 ⾃自動加上 strict 模式 (JavaScript) @ MSDN arguments.callee 不能⽤用 block 中不可宣告函式 call 、 apply 指定 this ⾏行為改變 函式中 this ⾏行為改變

Slide 39

Slide 39 text

arguments.callee 不能⽤用 匿名函式中指向函式本⾝身 遞迴呼叫 "use strict"; 
 
 setTimeout(function() {
 setTimeout(arguments.callee, 1000);
 }, 1000); JavaScript 錯誤 "use strict"; 
 
 setTimeout(function f() {
 setTimeout(f, 1000);
 }, 1000); 最佳化 IE9 (含) 以下有 bug

Slide 40

Slide 40 text

block 中不可宣告函式 function declaration "use strict";
 
 if(Windows) {
 function f() { console.log('hasWinRT'); }
 } JavaScript 錯誤 "use strict";
 
 if(Windows) {
 var f = function() { console.log('hasWinRT'); }
 } 改⽤用 function expression

Slide 41

Slide 41 text

call 、 apply 指定 this ⾏行為改變 "use strict";
 
 function f() { console.log(this); }
 
 f.call(null); // null
 f.call(undefined); // undefined ⾮非 Strict 模式、 window "use strict";
 
 f.apply(null, [1, 2, 3]); 使⽤用⺫⽬目的為第⼆二個參數

Slide 42

Slide 42 text

函式中 this ⾏行為改變 IE9 、 bug IE10 (原) 、 bug "use strict";
 
 f(); // undefined
 
 function f() { console.log(this); } ⾮非 Strict 模式、 window

Slide 43

Slide 43 text

"use strict"; 能拿掉嗎? 嚴謹好、事出必有因 煩 拿掉還沒碰到問題

Slide 44

Slide 44 text

WinJS 實踐 Promise 物件 Observable 物件 Single-page navigation

Slide 45

Slide 45 text

Promise 物件 Promise/A Promise/B Promise/D WinJS.Promise 、 jQuery Deferred 物件 Promise/A 不太相同

Slide 46

Slide 46 text

WinJS.Promise 超過 0.5 秒、⾮非同步、吐回 Promise 物件 messageDialog.showAsync() WinJS.Application.local.readText() WinJS.xhr 與 callback 相⽐比 語意清晰

Slide 47

Slide 47 text

AJAX a.php -> b.php -> c.php var xhr = new XMLHttpRequest();
 
 xhr.open('GET', 'a.php', true);
 xhr.onreadystatechange(function(http) {
 if(http.readyState == 4 && http.status == 200) {
 xhr.open('GET', 'b.php', true);
 xhr.onreadystatechange(function(http) {
 if(http.readyState == 4 && http.status == 200) {
 xhr.open('GET', 'c.php', true);
 xhr.onreadystatechange(function(http) {
 if(http.readyState == 4 && http.status == 200) {
 // ...
 }
 })
 xhr.send();
 } })
 xhr.send(); } }); xhr.send();

Slide 48

Slide 48 text

AJAX a.php -> b.php -> c.php WinJS.xhr({ url: 'a.php' })
 .then(function() { return WinJS.xhr({ url: 'b.php' }); })
 .then(function() { return WinJS.xhr({ url: 'c.php' }); })
 .done(function() { /* ... */ });

Slide 49

Slide 49 text

AJAX a.php b.php c.php 同時送出 等三者皆完成
 
 再下⼀一步
 
 不⽤用 Promise

Slide 50

Slide 50 text

AJAX a.php b.php c.php 同時送出 WinJS.Promise.join([
 WinJS.xhr ({ url: 'a.php' }),
 WinJS.xhr ({ url: 'b.php' }),
 WinJS.xhr ({ url: 'c.php' })])
 .done(function() { /* ... */ });

Slide 51

Slide 51 text

視情況 AJAX a.php 或 b.php 使⽤用情境 例 多元登⼊入 var xhr = XMLHttpRequest();
 
 if(type === 'A') {
 xhr.open('GET', 'a.php', true);
 xhr.onreadystatechange(function(http) {
 if(http.readyState == 4 && http.status == 200) {
 // http -> result
 f(result);
 }
 });
 xhr.send();
 }
 else {
 xhr.open('GET', 'b.php', true);
 xhr.onreadystatechange(function(http) {
 if(http.readyState == 4 && http.status == 200) {
 // http -> result
 f(result);
 }
 });
 xhr.send();
 }
 
 function f(result) { /* ... */ }

Slide 52

Slide 52 text

視情況 AJAX a.php 或 b.php var promise;
 
 if(type === 'A')
 promise = WinJS.xhr({ url : 'a.php' }).then(function(data){ /* ... */ });
 else
 promise = WinJS.xhr({ url : 'b.php' }).then(function(data) { /* ... */ }); 
 
 promise.done(function(result) { /* ... */ });

Slide 53

Slide 53 text

有值直接⽤用、沒值 AJAX a.php if(localStorage.x)
 f(localStorage.x);
 else {
 var xhr = XMLHttpRequest();
 xhr.open('GET', 'a.php', true);
 xhr.onreadystatechange(function(http) {
 if(http.readyState == 4 && http.status == 200) {
 // http -> result
 f(result);
 }
 });
 xhr.send();
 }
 
 function f(result) { /* ... */ };

Slide 54

Slide 54 text

有值直接⽤用、沒值 AJAX a.php var promise;
 
 if(localStorage.x)
 promise = WinJS.Promise.as(localStorage.x);
 else
 promise = WinJS.xhr({ url : 'a.php' }).then(function(data) { /* ... */ }); 
 
 promise.done(function(result) { /* ... */ }); WinJS.Promise.as ⾮非 Promies 轉成 Promise

Slide 55

Slide 55 text

⾃自⼰己兜 Promise 物件 Promise 內部 callback 實作 參考 WinJS.xhr 原始碼 var promise = new WinJS.Promise(function(complete, error, progress) {
 setTimeout(function() {
 // ...
 complete('DEMO');
 }, 3000);
 });

Slide 56

Slide 56 text

setPromise 待 Promise 執⾏行完畢、 Event 才完畢 app.onready = function (ev) {
 ev.detail.setPromise(
 WinJS.Application.roaming.writeText("time.txt", new Date())
 );
 };

Slide 57

Slide 57 text

Observable 物件 var target = document.getElementById('target'), 
 a = { x : 1 },
 b = WinJS.Binding.as(a);
 
 b.bind('x', function(newVal, oldVal) { target.innerHTML = newVal; }); 
 
 console.log(target.innerHTML); // 1
 
 b.x = 2;
 console.log(target.innerHTML); // 2
 
 b.x = 3; 
 console.log(target.innerHTML); // 3

Slide 58

Slide 58 text

Observable 物件 ECMAScript 5 Object getter setter Observable Proxy WinJS.Binding WinJS.Binding.as WinJS.Binding.define … WinJS 原始碼

Slide 59

Slide 59 text

Single-page navigation Quickstart: Using single-page navigation WinJS.UI.Pages 、 WinJS.Navigation 官⽅方建議使⽤用、較像 App

Slide 60

Slide 60 text

Single-page navigation WinJS.UI.Pages.define("/pages/home/home.html", {
 ready : function (element, options) {
 WinJS.Utilities.query("a").listen("click", function(ev) {
 ev.preventDefault();
 WinJS.Navigation.navigate(ev.target.href);
 }, false);
 }
 }); 記得寫、否則

Slide 61

Slide 61 text

Windows App Cert Kit 簡稱 WACK 或 Windows ACK App 上架前 JavaScript 特有不通過 UTF-8 檔案編碼 Bytecode 產⽣生

Slide 62

Slide 62 text

UTF-8 檔案編碼 檔案開頭要有 BOM jQuery 待續 … 官⽅方說法、BOM 提⾼高 15 – 20% 效能

Slide 63

Slide 63 text

Bytecode 產⽣生 App 內 JavaScript 存為 Bytecode 不通過處理步驟 本機電腦 App 移除 組態選單 Release 專案 -> 市集 -> 建⽴立應⽤用程式套件 精靈、 Windows App Cert Kit

Slide 64

Slide 64 text

Bytecode 產⽣生

Slide 65

Slide 65 text

Bytecode 產⽣生

Slide 66

Slide 66 text

Bytecode 產⽣生

Slide 67

Slide 67 text

Bytecode 產⽣生

Slide 68

Slide 68 text

⽴立即啟動!免費開發⼈人員帳⼾戶!!
 Windows Store / Windows Azure / Windows Phone 擁有 MSDN 訂閱 「取得代碼」後進⾏行註冊 http://aka.ms/startmsdn 優惠內容: Windows Store / Windows Phone – 啟⽤用後12個⽉月, 完全免費! Windows Azure – 訂閱期間, 每⽉月固定的免費使⽤用量!

Slide 69

Slide 69 text

Connect. Share. Discusss http://www.microsoft.com/taiwan/ techdays2012/ Microsoft Certification & Training Resources http://www.microsoft.com/learning/zh/tw/ Resources for IT Professionals http://social.technet.microsoft.com/Forums/ zh-tw/categories/ Resources for Developers http://social.msdn.microsoft.com/Forums/zh- tw/categories/ Resources

Slide 70

Slide 70 text

No content

Slide 71

Slide 71 text

請協助完成「本課程問卷」,並在離開 教室時交給⼯工作⼈人員! 填妥⼤大會背包中的⼤大會問卷,可於活動 第三天兌換問卷禮哦! 感謝您的合作。

Slide 72

Slide 72 text

No content