2014年09月02日更新
今天用了一下WebBrowser,在使用過程中也遇到了一些問題,在這里做一下記錄
雖然WebBrowser比較重,會比較影響性能(除非一定要用到它,否則盡量少用),但有時候還是得用WebBrowser來作為顯示的控件,比如WP上有2048渲染的限制,我們可以通過WebBrowser來顯示長文本,還有富文本信息(新聞)等,但使用起來也並不方便,這里做一下記錄
1、禁止縮放
<head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <!--這里禁止縮放--> <meta content="width=device-width,user-scalable=no" name="viewport"> <style type="text/css"> img { width: 100%; } </style> </head>
2、JS調用C#代碼(Notify)
我們可以在JS中發送一個消息到后台代碼,告知需要做什么操作
比如在頁面中有一個電話號碼,當用戶點擊的時候,我們需要調用系統的API調用電話的Task,或者發郵件功能,又或者比較常見的,我們希望點擊頁面里面的圖片的時候可以顯示一張大圖,並可以保存圖片
1)由於JS只能向后台代碼發送字符串消息,為了區分不同的消息,我們先統一一下消息格式
/// <summary> /// JS消息格式 /// </summary> public class JsInvokeModel { [JsonProperty("type")] public string Type { get; set; } [JsonProperty("content1")] public string Content1 { get; set; } [JsonProperty("content2")] public string Content2 { get; set; } [JsonProperty("content3")] public string Content3 { get; set; } }
2)Xaml
<phone:WebBrowser x:Name="Browser" Grid.Row="1" IsScriptEnabled="True" ScriptNotify="Browser_OnScriptNotify" LoadCompleted="Browser_OnLoadCompleted" Source="http://www.baidu.com" />
3、.cs:JS通知事件函數
private void Browser_OnScriptNotify(object sender, NotifyEventArgs e) { //這個事件函數可以監聽到JS通知的消息,消息類型為文本 //這里統一消息格式為:JsInvokeModel var model = JsonConvert.DeserializeObject<JsInvokeModel>(e.Value); switch (model.Type) { case "phoneCall": PhoneCall(model.Content1, model.Content2); break; case "sendEmail": SendEmail(model.Content1, model.Content2, model.Content3); break; case "image": MessageBox.Show(string.Format("圖片:{0}", model.Content1)); break; case "text": MessageBox.Show(string.Format("文本:{0}", model.Content1)); break; } } public void SendEmail(string to, string body, string subject) { var task = new EmailComposeTask { Body = body, To = to, Subject = subject, }; task.Show(); } public void PhoneCall(string name, string phone) { var task = new PhoneCallTask { DisplayName = name, PhoneNumber = phone }; task.Show(); }
4)示例文件(HTML)

<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <!--這里禁止縮放--> <meta content="width=device-width,user-scalable=no" name="viewport"> <style type="text/css"> img { width: 100%; } </style> </head> <body> <div id="content"> <a onclick="phoneCall('中國移不動', '10086')">打電話</a> <br/> <a onclick="invokeText('js調用C#方法')">Invoke C#</a> <br /> <a onclick="sendEmail('zhengbomo@hotmail.com', '測試郵件,從WebBrowser調用', '測試')">發郵件</a> <br /> <br /> <div>普通文本普通文本普通文本普通文本普通文本普通文本普通文本普通文本普通文本普通文本普通文本</div> <!--圖片--> <img src="http://s1.dwstatic.com/group1/M00/F3/AD/9c26c21d6111fe1e2c2d9b301ad2fe66.jpg" alt="" /> <img src="http://s1.dwstatic.com/group1/M00/E0/E7/a43758af471383c14f2706e8b4cf2633.jpg" alt="" /> <img src="http://s1.dwstatic.com/group1/M00/B4/F7/f3cbe9a238c60807ea3cd82e3252e2a3.jpg" alt="" /> <!--引用安裝目錄的資源--> <img src="../emoji1.png" alt="" /> <!--引用本地文件--> <img src="x-wmapp0:Assets/AlignmentGrid.png" alt="" /> </div> <!--引用本地js--> <script src="../../Scripts/json2.min.js"></script> <!--<script src="x-wmapp0:Scripts/json2.min.js"></script>--> <script type="text/javascript"> window.onload = function () { //動態加載Script //var myScript = document.createElement("script"); //myScript.type = "text/javascript"; //myScript.src = "x-wmapp0:Scripts/json2.min.js"; //document.body.appendChild(myScript); var imgs = document.getElementsByTagName("img"); for (var i = 0, len = imgs.length; i < len; i++) { imgs[i].onclick = function (e) { var jsonObj = { type: 'image', content1: this.src }; notify(JSON.stringify(jsonObj)); }; } }; //給C#后台代碼調用的方法 function InvokeFromCode() { alert("C#調用js不參數的方法"); } //給C#后台代碼調用的方法 function InvokeFromCodeWithParam(text) { document.getElementById("content").innerHTML = text; return "15"; } //發送文本消息 function invokeText(text) { var jsonObj = { type: 'text', content1: text }; notify(JSON.stringify(jsonObj)); } //發送郵件 function sendEmail(to, body, subject) { var jsonObj = { type: 'sendEmail', content1: to, content2: body, content3: subject }; notify(JSON.stringify(jsonObj)); } //調用打電話的方法 function phoneCall(name, phone) { //序列化方法 var jsonObj = { type: 'phoneCall', content1: name, content2:phone }; notify(JSON.stringify(jsonObj)); } //發送消息通知后台代碼 function notify(msg) { window.external.Notify(msg); } </script> </body> </html>
5)調用
//拷貝安裝目錄文件到本地 await StorageHelper.Instance.CopyPackageFileToLocalAsync("Assets/Html/default.html", null, true); Browser.Navigate(new Uri("Assets/Html/default.html", UriKind.Relative));
3、C#調用JS方法
1、使用eval方法執行自定義代碼
2、使用x-wmapp0:引用本地路徑
3、使用 json2 進行json序列化
注意:后台代碼調用JS的時候一般在 LoadCompleted 事件中調用
下面代碼調用的方法見示例文件:default.html
//1、獲得HTML代碼(兩種方式) var html = Browser.SaveToString(); var html = Browser.InvokeScript("eval", new[] {"document.documentElement.outerHTML;"}); //2、調用js方法(不帶參數) Browser.InvokeScript("InvokeFromCode"); //3、調用js方法(帶參數,返回值) var res = Browser.InvokeScript("InvokeFromCodeWithParam", new[] { "從后台代碼調用js修改html" }); //4、動態加載js庫(x-wmapp0:表示本地路徑) var js = @" var myScript = document.createElement(""script""); myScript.type = ""text/javascript""; myScript.src = ""x-wmapp0:Scripts/json2.min.js""; document.body.appendChild(myScript);"; Browser.InvokeScript("eval", js); //5、調用js執行自定義代碼(為圖片添加點擊事件,並通知) js = @" var imgs = document.getElementsByTagName(""img""); for (var i = 0, len = imgs.length; i < len; i++) { imgs[i].onclick = function (e) { var jsonObj = { type: 'image', content1: this.src }; window.external.Notify(JSON.stringify(jsonObj)); }; }"; Browser.InvokeScript("eval", js);
4、Browser導航
//刷新 Browser.InvokeScript("eval", "history.go()"); //后退(下面兩種方式) Browser.InvokeScript("eval", "history.go(-1)"); Browser.GoBack(); //前進(下面兩種方式) Browser.InvokeScript("eval", "history.go(1)"); Browser.GoForward();
5、緩存
WebBrowser只提供了清除緩存和Cookie的方法,沒有找到設置緩存的相關方法
Browser.ClearCookiesAsync();
Browser.ClearInternetCacheAsync();
6、常見問題
2014年10月8日更新:
使用WebBrowser.NavigateToString(string html)要注意,在WP8.0上,這里的html字符串中不要包括HTML文件的頭部文檔類型聲明,否則會出現無法解析的問題
<!DOCTYPE html>
我們把 <!DOCTYPE html> 刪除之后,則可以正常渲染,這個問題在WP8.0的時候才會,在WP8.1之后不會
最后:
動態資源的加載可以用於我們不能控制html內容的頁面,比如我們訪問百度頁面,里面有很多圖片,我們需要點擊圖片的時候,可以彈出框顯示一張大圖,同時可以讓用戶保存,這個時候我們可以動態加載JS,去監聽所有的點擊事件,這樣,所有的頁面的圖片我們都能監聽到點擊事件了,而且能獲取到圖片鏈接
個人能力有限,如果上文有誤或者您有更好的實現,可以給我留言
轉載請注明出處:http://www.cnblogs.com/bomo/p/3949994.html