如何接收 HTML (HTML)

[ 本文适用于编写 Windows 运行时应用的 Windows 8.x 和 Windows Phone 8.x 开发人员。如果你要针对 Windows 10 进行开发,请参阅 最新文档 ]

HTML 内容可以包括各种内容,包括文本、图像和其他信息。以下介绍你的应用可如何接收用户希望共享的 HTML 内容。

将此功能添加到你的应用之后,请考虑也接受文本格式的内容。文本很容易就可以转换为 HTML,因此添加对此格式的支持可以帮助你确保你的应用更常对用户可用。要了解详细信息,请参阅如何接收文本

你需要了解的内容

技术

先决条件

  • 你应当熟悉 Visual Studio 及其关联模板。
  • 你应当熟悉 JavaScript。

说明

步骤 1: 支持“共享”合约。

你必须首先声明你的应用支持“共享”合约,然后你的应用才能接收共享内容。此合约从根本上让系统知道你的应用可用于接收内容。如果你使用 Microsoft Visual Studio 模板创建应用,以下是支持“共享”合约的方法:

  1. 打开清单文件。该文件的名称类似 package.appxmanifest
  2. 打开“声明”选项卡。
  3. 从“可用声明”列表中,选择“共享目标”。****

步骤 2: 指定你的应用支持 HTML。

若要指定你支持数据格式的 HTML,请执行以下操作:

  1. 打开清单文件。
  2. 在“数据格式”****部分中,单击“新增”。
  3. 键入 html。

注意  当为共享目标协定激活你的应用时,你可以指定一个不同的输入点。若要完成此操作,请在程序包清单中的“共享目标”声明的“应用设置”部分中修改“起始页”条目。****强烈建议你还使用一个单独的 JavaScript 文件来处理此页面的激活。例如,检查共享内容目标应用示例

 

步骤 3: 添加要用来检测应用在何时激活的事件处理程序。

当用户选择你的应用来共享内容时,系统会激活你的应用。由于可通过许多方式实现该操作,因此你需要向你的 activated 事件处理程序添加代码来检测激活原因。这可通过检查 kind 属性的值来完成。

app.onactivated = function (args) {
    if (args.detail.kind === activation.ActivationKind.launch) {
        // The application has been launched. Initialize as appropriate.
    } else if (args.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.shareTarget) {
        ...
    }
};

如果你为共享目标协定使用某个专用起始页,那么你可以跳过检查 kind 属性

步骤 4: 获取 ShareOperation 对象。

ShareOperation 对象包含你的应用为了获取用户要共享的内容而所需的全部数据。

shareOperation = args.detail.shareOperation;

步骤 5: 快速从已激活的事件处理程序返回。

activated 事件处理程序必须快速返回。将 activated 事件处理程序中的某个异步事件排入队列,这样共享数据处理会在已激活事件返回后发生。

WinJS.Application.addEventListener("shareready", shareReady, false);
WinJS.Application.queueEvent({ type: "shareready" });

剩下的步骤将实现 shareReady 函数。

步骤 6: 查明 DataPackageView 是否包含 HTML

ShareOperation 对象包含一个 DataPackageView 对象。DataPackageView 对象本质上是源应用在创建数据时所使用的 DataPackage 对象的只读版本。使用此对象来查明是否以 HTML 格式提供正在共享的内容。

if (shareOperation.data.contains(Windows.ApplicationModel.DataTransfer.StandardDataFormats.html)) {
    // Code to get HTML goes here.
}

检查 DataPackage 是否包含你感兴趣的数据格式是很好的做法,即使你的应用仅支持一种格式也是如此。这更便于在以后支持其他数据格式类型和文件格式。

步骤 7: 处理 HTML。

要获取 HTML 内容,请调用 getHtmlFormatAsync 方法。此方法在 HTML 格式规范中返回 HTML 内容。你可以使用 DataTransfer.HtmlFormatHelper.getStaticFragment 从 HTML 格式提取 HTML 片段。产生的片段也进行过净化以删除掉任何动态内容(如脚本标记),且可以安全地在你的应用程序中呈现。

shareOperation.data.getHtmlFormatAsync().then(function (htmlFormat) {
    var htmlFragment = Windows.ApplicationModel.DataTransfer.HtmlFormatHelper.getStaticFragment(htmlFormat);
    // In this example, we only display the HTML. To do this, you need 
    // a <div> element with an id of "output" in your HTML page.

    // In your app, replace this with whatever is appropriate for your scenario.
    document.getElementById("output").innerHTML = htmlFragment;
});

当然,你对 HTML 进行的处理取决于你的应用。

步骤 8: 为 HTML 解析任何本地图像引用。

此共享源应用可能会在 HTML 中包含图像,这些图像位于其本地存储上下文(例如,ms-appx、ms-appdata 等)中。这种情况下,源应用应该已使用适当的引用填充资源映射,以使共享目标能够访问这些资源。

要从源应用解析本地图像,请使用 resourceMap 属性查找每个图像引用并获取相应的 RandomAccessStreamReference。以下示例创建对象统一资源标识符 (URI) 以在 HTML 中呈现图像。在你的应用中,将此代码替换为适合你的方案的任何修改。

var images = document.getElementById("output").getElementsByTagName("img");
if (images.length > 0) {
    shareOperation.data.getResourceMapAsync().done(function (resourceMap) {
        if (resourceMap.size > 0) {
            for (var i = 0, len = images.length; i < len; i++) {
                var streamReference = resourceMap[images[i].getAttribute("src")];
                if (streamReference) {
                    // Call a helper function to map the image element's src to a 
                    // corresponding blob URL generated from the streamReference.
                    setResourceMapURL(streamReference, images[i]);
                }
            }
        }
    });
}

步骤 9: 调用 reportCompleted。

在你的应用完成共享内容之后,请调用 reportCompleted。在你调用此方法之后,系统会关闭你的应用。

shareOperation.reportCompleted();

备注

检查我们的共享内容目标应用示例代码示例以了解应用作为共享的一部分接收图像的整个端对端体验。

完整示例

var shareOperation = null;

function setResourceMapURL(streamReference, imageElement) {
    if (streamReference) {
        streamReference.openReadAsync().done(function (imageStream) {
            if (imageStream) {
                var url = URL.createObjectURL(imageStream, { oneTimeOnly: true });
                imageElement.src = url;
            }
        }, function (e) {
            imageElement.alt = "Failed to load";
        });
    }
}

function shareReady(args) {
    if (shareOperation.data.contains(Windows.ApplicationModel.DataTransfer.StandardDataFormats.html)) {
        shareOperation.data.getHtmlFormatAsync().then(function (htmlFormat) {
            var htmlFragment = Windows.ApplicationModel.DataTransfer.HtmlFormatHelper.getStaticFragment(htmlFormat);
            // In this example, we only display the HTML. To do this, you need 
            // a <div> element with an id of "output" in your HTML page.
            // In your app, replace this with whatever is appropriate for your scenario.
            document.getElementById("output").innerHTML = htmlFragment;

            // Now we loop through any images and use the resourceMap to map each
            // image element's src.
            var images = document.getElementById("output").getElementsByTagName("img");

            if (images.length > 0) {
                shareOperation.data.getResourceMapAsync().done(function (resourceMap) {
                    if (resourceMap.size > 0) {
                        for (var i = 0, len = images.length; i < len; i++) {
                            var streamReference = resourceMap[images[i].getAttribute("src")];
                                if (streamReference) {
                                    // Call a helper function to map the image element's
                                    // src to a corresponding blob URL generated from the
                                    // streamReference.
                                    setResourceMapURL(streamReference, images[i]);
                                }
                        }
                    }
                });
            }
        });
    } 
}

app.onactivated = function (args) {
    if (args.detail.kind === activation.ActivationKind.launch) {
        // The application has been launched.
        args.setPromise(WinJS.UI.processAll());
    } else if (args.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.shareTarget) {
        // This application has been activated for the Share contract
        args.setPromise(WinJS.UI.processAll());

        // We receive the ShareOperation object as part of the eventArgs.
        shareOperation = args.detail.shareOperation;

        // We queue an asychronous event so that working with the ShareOperation 
        // object does not block or delay the return of the activation handler.
        WinJS.Application.addEventListener("shareready", shareReady, false);
        WinJS.Application.queueEvent({ type: "shareready" });
    }
};

相关主题

共享内容目标应用示例

共享和交换数据

如何接收文件

如何接收链接

如何接收文本

快速入门:接收共享内容

DataPackage

Windows.ApplicationModel.DataTransfer

Windows.ApplicationModel.DataTransfer.Share

调试目标应用指南