如何复制和粘贴 HTML (HTML)
12/11/2015
本文内容
[ 本文适用于编写 Windows 运行时应用的 Windows 8.x 和 Windows Phone 8.x 开发人员。如果你要针对 Windows 10 进行开发,请参阅 最新文档 ]
复制和粘贴 HTML 内容不同于复制和粘贴其他基本格式(如文本或链接)。遇到的主要挑战是,内容可能包含对其他内容的引用。例如,它可能包含其 src 属性引用本地存储的图像文件的 img 标记。当用户复制此内容时,他们期望同时包含文本和图像。支持复制和粘贴 HTML 的应用需要考虑如何处理这些引用以确保用户能够复制和粘贴他们所需的内容。
若要帮助你按用户期望的方式复制和粘贴 HTML,则 Windows.ApplicationModel.DataTransfer 命名空间包含一些函数,这些函数可帮助捕获引用的元素,如图像。我们将向你展示具体做法。
查看我们的剪贴板示例应用以便获得介绍如何复制和粘贴其他类型数据的完整示例。
你需要了解的内容
技术
先决条件
你应当了解如何使用 JavaScript 来标识用户已选择的 HTML,并在该选择范围内找到子元素(如 img 标记)的实例。
你应当熟悉 Visual Studio 及其关联模板。
你应当熟悉 JavaScript。
将 HTML 复制到剪贴板
var dataPackage = new Windows.ApplicationModel.DataTransfer.DataPackage();
获取 HTML 内容。
下面我们从 HTML 元素获取内容:
var htmlFragment = document.getElementById("htmlTextToCopy").innerHTML;
准备 HTML 内容以便进行剪贴板操作。
使用 HtmlFormatHelper.CreateHtmlFormat 方法准备 HTML 内容。该方法添加必需的标头并且确保将 HTML 设置为适合剪贴板操作的正确格式。
var htmlFormat = Windows.ApplicationModel.DataTransfer.HtmlFormatHelper.createHtmlFormat(htmlFragment);
将 HTML 内容添加到 DataPackage 对象。
dataPackage.setHtmlFormat(htmlFormat);
用内容引用填充资源映射。
如果用户选择了包含对其他内容(如本地存储的图像文件)的引用的 HTML,则需要将这些引用添加到 DataPackage.ResourceMap 属性中。下面是添加图像引用所需的步骤:
var imagePath = document.getElementById("localImage").src;
var imageUri = new Windows.Foundation.Uri(imagePath);
var streamRef = Windows.Storage.Streams.RandomAccessStreamReference.createFromUri(imageUri);
dataPackage.resourceMap.insert(imagePath, streamRef);
将内容复制到剪贴板。
Windows.ApplicationModel.DataTransfer.Clipboard.setContent(dataPackage);
粘贴剪贴板中的 HTML
获取剪贴板的内容。
var dataPackageView = Windows.ApplicationModel.DataTransfer.Clipboard.getContent();
检查剪贴板是否包含 HTML 数据。
if (dataPackageView.contains(Windows.ApplicationModel.DataTransfer.StandardDataFormats.html)) {
...
}
如果剪贴板包含 HTML,则按照用户的指示检索该 HTML 并将其添加到文档对象模型 (DOM)。
小心 请注意,来自其他应用程序的 HTML 不受信任,因此你不应该显示它,除非你确定此 HTML 没有任何动态内容。使用 DataTransfer.HtmlFormatHelper.GetStaticFragment 方法获取共享的 HTML 内容(没有任何动态元素,如脚本标记)。
var htmlFragment = Windows.ApplicationModel.DataTransfer.HtmlFormatHelper.getStaticFragment(htmlFormat);
document.getElementById("htmlOutput").innerHTML = htmlFragment;
通过以下步骤使用资源映射的内容替换本地图像文件 URL(如果有):
...
var images = document.getElementById("htmlOutput").getElementsByTagName("img");
// Check first if there are any images (img tags) in the fragment, because
// calling the getResourceMapAsync method can be resource intensive.
if (images.length > 0) {
dataPackageView.getResourceMapAsync().done(function (resourceMap) {
// Check whether the resourceMap contains any items.
if (resourceMap.size > 0) {
for (var i = 0, len = images.length; i < len; i++) {
var imageElement = images[i];
// Look up RandomAccessStreamReference value corresponding to this
// image's SRC property.
var streamRef = resourceMap.lookup(imageElement.getAttribute("src"));
if (streamRef) {
// Generate blob URL, and replace contents of the SRC property.
replaceSrcURL(imageElement, streamRef);
}
}
}
});
}
...
function replaceSrcURL(imageElement, streamRef) {
// Map the image element's src to a corresponding blob URL generated from the streamReference.
streamRef.openReadAsync().done(function (imageStream) {
var blobObject =
window.MSApp.createBlobFromRandomAccessStream(imageStream.contentType, imageStream);
var blobUrl = window.URL.createObjectURL(blobObject, { oneTimeOnly: true });
imageElement.src = blobUrl;
}, function (e) {
displayError("Error opening stream corresponding to the image element with SRC=\"" +
imageElement.getAttribute("src") + "\". Error: " + e);
});
}
完整示例
该示例显示如何将带有嵌入图像的 HTML 复制到剪贴板。
function copyHTML() {
// Create the DataPackage object.
var dataPackage = new Windows.ApplicationModel.DataTransfer.DataPackage();
// Get the HTML content of an element.
var htmlFragment = document.getElementById("htmlTextToCopy").innerHTML;
// Prepare the HTML for Clipboard operations.
var htmlFormat =
Windows.ApplicationModel.DataTransfer.HtmlFormatHelper.createHtmlFormat(htmlFragment);
if (htmlFormat !== "") {
// Add the HTML to the DataPackage object
dataPackage.setHtmlFormat(htmlFormat);
// Populate the resourceMap with RandomAccessStreamReference objects
// corresponding to the local image file embedded in the HTML.
var imagePath = document.getElementById("someEmbeddedImage").src;
var imageUri = new Windows.Foundation.Uri(imagePath);
var streamRef = Windows.Storage.Streams.RandomAccessStreamReference.createFromUri(imageUri);
dataPackage.resourceMap.insert(imagePath, streamRef);
}
try {
// Copy the HTML content to Clipboard.
Windows.ApplicationModel.DataTransfer.Clipboard.setContent(dataPackage);
displayStatus("Text and HTML formats have been copied to Clipboard");
} catch (e) {
// Copying data to Clipboard can potentially fail if, for example another app is holding
// the Clipboard open.
displayError("Error copying content to Clipboard: " + e + ". Try again.");
}
}
该示例显示如何获取剪贴板中存储的 HTML,以及 HTML 内容中引用的任何图像。
function pasteHTML() {
var dataPackageView = Windows.ApplicationModel.DataTransfer.Clipboard.getContent();
if (dataPackageView.contains(Windows.ApplicationModel.DataTransfer.StandardDataFormats.html)) {
// Get the HTML Format (CF_HTML) from DataPackageView.
dataPackageView.getHtmlFormatAsync().done(function (htmlFormat) {
// Extract the HTML fragment.
var htmlFragment =
Windows.ApplicationModel.DataTransfer.HtmlFormatHelper.getStaticFragment(htmlFormat);
// Add the fragment to the DOM.
document.getElementById("htmlOutput").innerHTML = htmlFragment;
// Replace local image file URLs, if any, with the contents of the resourceMap.
var images = document.getElementById("htmlOutput").getElementsByTagName("img");
// Check first if there are any images (img tags) in the fragment, because
// calling the getResourceMapAsync method can be resource intensive.
if (images.length > 0) {
dataPackageView.getResourceMapAsync().done(function (resourceMap) {
// Check whether the resourceMap contains any items.
if (resourceMap.size > 0) {
for (var i = 0, len = images.length; i < len; i++) {
var imageElement = images[i];
// Look up RandomAccessStreamReference value corresponding to this
// image's SRC property.
var streamRef = resourceMap.lookup(imageElement.getAttribute("src"));
if (streamRef) {
// Generate blob URL, and replace contents of the SRC property.
replaceSrcURL(imageElement, streamRef);
}
}
}
});
}
}, function (e) {
displayError("Error retrieving HTML format from Clipboard: " + e);
});
} else {
document.getElementById("scenario1HtmlOutput").innerText =
"HTML format is not available in clipboard";
}
}
function replaceSrcURL(imageElement, streamRef) {
// Map the image element's src to a corresponding blob URL generated from the streamReference.
streamRef.openReadAsync().done(function (imageStream) {
var blobObject =
window.MSApp.createBlobFromRandomAccessStream(imageStream.contentType, imageStream);
var blobUrl = window.URL.createObjectURL(blobObject, { oneTimeOnly: true });
imageElement.src = blobUrl;
}, function (e) {
displayError("Error opening stream corresponding to the image element with SRC=\"" +
imageElement.getAttribute("src") + "\". Error: " + e);
});
}
相关主题