Metro Web应用开发中页面通信问题解决方法

最近在开发Win8应用,遇到Win8 native context和web context 通信的问题,这里将相应的方法分析一下。Win8的介绍和详细信息可以在MSDN上面获得,也可以参考本人介绍开发者预览版时的系列博客

Win8 应用开发介绍(一) Win8新特性\
Win8 应用开发介绍(二) Win8应用为王\
Win8 应用开发介绍(三) Win8开发者工具\
Win8 应用开发介绍(四) Win8应用开发步骤\
Win8 应用开发介绍(五) Win8硬件支持和安全性\
Win8 应用开发介绍(六) Win8伴你随行\

1. 问题描述

Win8可是使用HTML, JavaScript方式来开发Metro Style App。那么传统的HTML网页中,加载web端的JavaScript文件采用的代码方式仍然可以使用吗?如:

<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0></script>

答案是不可以,因为处于安全考虑,Win8不允许在开发Web Metro应用的时候不允许在Local context中加载一个remote URL。及即使把这个文件下载下来放在本地也是不可以的,因为它会操作HTML页面中的DOM。

在编译的时候会报错。

2.解决方法

将需要加载的页面放在Local Context的iFrame中。这样当Metro应用在运行的时候,iFrame中的页面其实可以理解为运行在Metro IE浏览器中,所以不存在Local Context不允许加载Remote URL的问题。

代码参考如下:

<!DOCTYPE html>

<html>

<head>

    <meta charset="utf-8" />

    <meta name="viewport" content="width=1024, height=768" />

    <title>WinWebApp1</title>

    <!-- WinJS references -->

    <link rel="stylesheet" href="/winjs/css/ui-dark.css" />

    <script src="/winjs/js/base.js"></script>

    <script src="/winjs/js/wwaapp.js"></script>

    <script src="/winjs/js/ui.js"></script>

    <script src="/winjs/js/controls.js"></script>

    <!-- WinWebApp1 references -->

    <link rel="stylesheet" href="/css/default.css" />

    <script src="/js/default.js"></script>

</head>

<body>

    <header role="banner" aria-label="Header content">

        <div class="titleArea">

            <h1 class="pageTitle win-title" role="button" aria-label="Groups" tabindex="0">

                Metro Map App</h1>

        </div>

    </header>

    <div>

      <iframe id="mapIframe" src="file:///****.html" width="1280px" height="800px"></iframe>

    </div>

</body>

</html>

src=file:///****.html 或者src=http://****.html 是需要加载web context 的页面,在相应的html文件中可以自由加载remote URL的内容。

在页面中的关系图如下:

通信

现在的问题出现了,Web Context如何和Local Context通信了。Win8 IE全面支持了HTML5,在HTML5中可以使用HTML5 postMessage method在不通的页面中进行通信。

假设我们在Local Context中新建一个button,代码如下:

<button onclick="ZoomOut();">Zoom Out</button>

在JavaScript中,添加ZoomOut函数:

<script>

function ZoomOut(dx, dy) {

    var xMsg = { method: 'zoomout' };

    mapIframe.postMessage( “ ***** Post your message ”);

}

</script>

在Web Context中,添加receiveMessage(event) 参考代码如下:

function receiveMessage(event) {

  switch (event.data.method) {


	......


    case 'zoomout':

      var currentZoom = map.getZoom();

      map.setView({ zoom: currentZoom - 1 });

      break;

  }

}

本篇完。
参考文章:http://alastaira.wordpress.com/2011/09/26/creating-a-windows-8-metro-slippy-map-application/

Para obtener más información sobre las optimizaciones del compilador, consulte el aviso sobre la optimización.