1# 使用Web组件与系统剪贴板交互处理网页内容 2<!--Kit: ArkWeb--> 3<!--Subsystem: Web--> 4<!--Owner: @zourongchun--> 5<!--Designer: @zhufenghao--> 6<!--Tester: @ghiker--> 7<!--Adviser: @HelloCrease--> 8 9开发者能够通过Web组件和系统剪贴板进行交互,实现各种类型数据的复制和粘贴。支持通过[菜单](web_menu.md)、键盘快捷键以及[W3C剪贴板接口](https://www.w3.org/TR/clipboard-apis/)对网页内容执行剪切、复制和粘贴操作。 10 11## 通过菜单或键盘快捷键与系统剪贴板交互 12 13开发者能够自定义菜单中的功能选项,当用户选择特定选项时,开发者可以通过调用[cut](../reference/apis-arkweb/arkts-basic-components-web-WebContextMenuResult.md#cut9)、[copy](../reference/apis-arkweb/arkts-basic-components-web-WebContextMenuResult.md#copy9)、[copyImage](../reference/apis-arkweb/arkts-basic-components-web-WebContextMenuResult.md#copyimage9)、[paste](../reference/apis-arkweb/arkts-basic-components-web-WebContextMenuResult.md#paste9)、[pasteAndMatchStyle](../reference/apis-arkweb/arkts-basic-components-web-WebContextMenuResult.md#pasteandmatchstyle20)等接口,将网页中的文本、HTML或图片数据复制到系统剪贴板,或从系统剪贴板粘贴到网页的可输入区域。 14 15菜单功能接口的使用可参考[使用Web组件菜单处理网页内容](web_menu.md)。 16 17当设备有物理键盘时,用户也能够通过键盘快捷键:CTRL + X(剪切)、CTRL + C(复制)、CTRL + V(粘贴),与剪贴板进行交互。 18 19> **说明:** 20> 21> 通过[paste](../reference/apis-arkweb/arkts-basic-components-web-WebContextMenuResult.md#paste9)、[pasteAndMatchStyle](../reference/apis-arkweb/arkts-basic-components-web-WebContextMenuResult.md#pasteandmatchstyle20)接口访问系统剪贴板内容,需[申请访问剪贴板权限](../basic-services/pasteboard/get-pastedata-permission-guidelines.md):ohos.permission.READ_PASTEBOARD。 22 23## 通过W3C异步剪贴板接口与系统剪贴板交互 24 25[异步剪贴板接口(Async Clipboard API)](https://www.w3.org/TR/clipboard-apis/#async-clipboard-api)提供给网页开发者读写系统剪贴板的方法,这让Web应用程序可以实现剪切、复制和粘贴的功能。 26 27- writeText:将文本内容写入系统剪贴板。 28 29```javascript 30// 写入文本到剪贴板 31await navigator.clipboard.writeText("文本内容"); 32``` 33 34- write:将任意类型内容写入系统剪贴板。 35 36```javascript 37// 写入 HTML到剪贴板 38const clipboardItem = new ClipboardItem({ 39 'text/html': new Blob(["HTML内容"], { type: 'text/html' }) 40}); 41await navigator.clipboard.write([clipboardItem]); 42``` 43 44- readText:从系统剪贴板读取文本内容。 45 46```javascript 47// 从剪贴板读取文本 48const text = await navigator.clipboard.readText() 49``` 50 51- read():从系统剪贴板读取任意类型内容。 52 53```javascript 54// 从剪贴板读取 HTML 55const clipboardItems = await navigator.clipboard.read(); 56const htmlBlob = await clipboardItems[0].getType('text/html'); 57``` 58 59> **说明:** 60> 61> 通过异步剪贴板接口read()和readText()方法访问系统剪贴板内容,需[申请访问剪贴板权限](../basic-services/pasteboard/get-pastedata-permission-guidelines.md):ohos.permission.READ_PASTEBOARD。 62 63```ts 64// xxx.ets 65import { webview } from '@kit.ArkWeb'; 66 67@Entry 68@Component 69struct WebComponent { 70 controller: webview.WebviewController = new webview.WebviewController(); 71 72 build() { 73 Column() { 74 Web({ src: $rawfile("clipboard.html"), controller: this.controller }) 75 } 76 } 77} 78``` 79 80加载的html: 81 82```html 83<!--clipboard.html--> 84<!DOCTYPE html> 85<html lang="zh"> 86<head> 87 <meta charset="UTF-8"> 88 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 89 <title>Clipboard API demo</title> 90 <style> 91 #output { 92 margin-top: 20px; 93 border: 1px solid #ccc; 94 padding: 10px; 95 min-height: 50px; 96 } 97 .button-group { 98 margin-bottom: 10px; 99 } 100 </style> 101</head> 102<body> 103<h1>Clipboard API demo</h1> 104<div class="button-group"> 105 <button id="copyTextButton">复制文本</button> 106 <button id="copyHtmlButton">复制HTML</button> 107</div> 108 109<div class="button-group"> 110 <button id="pasteTextButton">粘贴文本</button> 111 <button id="pasteHtmlButton">粘贴HTML</button> 112 <button id="clearOutputButton">清空输入框</button> 113</div> 114 115<div id="result"></div> 116<div id="output" contenteditable="true"></div> 117 118<script> 119 const textContent = "这是一些文本内容"; 120 const htmlContent = `<strong><em>这是一些 HTML 内容</em></strong>`; 121 122 // writeText()接口 123 async function copyText() { 124 await navigator.clipboard.writeText(textContent); 125 document.getElementById('result').innerText = "文本已复制到剪贴板!"; 126 } 127 128 // write()接口 129 async function copyHtml() { 130 const clipboardItem = new ClipboardItem({ 131 'text/html': new Blob([htmlContent], { type: 'text/html' }) 132 }); 133 await navigator.clipboard.write([clipboardItem]); 134 document.getElementById('result').innerText = "HTML 已复制到剪贴板!"; 135 } 136 137 // readText()接口 138 async function pasteText() { 139 const text = await navigator.clipboard.readText(); 140 document.getElementById('output').innerText = text; 141 } 142 143 // read()接口 144 async function pasteHtml() { 145 const items = await navigator.clipboard.read(); 146 for (const item of items) { 147 const types = item.types; 148 if (types.includes('text/html')) { 149 const blob = await item.getType('text/html'); 150 const html = await blob.text(); 151 document.getElementById('output').innerHTML = html; 152 return; 153 } 154 } 155 document.getElementById('result').innerText = "剪贴板中没有 HTML 内容。"; 156 } 157 158 function clearOutput() { 159 document.getElementById('result').innerText = " "; 160 document.getElementById('output').innerHTML = ''; 161 } 162 163 // 事件监听 164 document.getElementById('copyTextButton').addEventListener('click', copyText); 165 document.getElementById('copyHtmlButton').addEventListener('click', copyHtml); 166 document.getElementById('pasteTextButton').addEventListener('click', pasteText); 167 document.getElementById('pasteHtmlButton').addEventListener('click', pasteHtml); 168 document.getElementById('clearOutputButton').addEventListener('click', clearOutput); 169</script> 170</body> 171</html> 172``` 173 174module.json5权限配置: 175 176**需要权限**:ohos.permission.READ_PASTEBOARD,应用访问剪贴板内容需[申请访问剪贴板权限](../basic-services/pasteboard/get-pastedata-permission-guidelines.md)。 177 178```json 179// module.json5 180{ 181 "module" : { 182 // ... 183 "requestPermissions":[ 184 { 185 "name" : "ohos.permission.READ_PASTEBOARD", 186 "reason": "$string:module_desc", 187 "usedScene": { 188 "abilities": [ 189 "FormAbility" 190 ], 191 "when":"inuse" 192 } 193 } 194 ] 195 } 196} 197``` 198 199 200 201## 通过W3C剪贴板事件接口与系统剪贴板交互 202 203[剪贴板事件(Clipboard Event)](https://www.w3.org/TR/clipboard-apis/#clipboard-events-and-interfaces)描述了与剪切板相关的cut、copy和paste事件。当用户执行剪切、复制或粘贴操作时,相应的事件将被触发。开发者可以通过监听这些事件,对系统剪贴板进行读写操作,或拦截默认行为,以更改复制或粘贴的结果。 204 205```ts 206// xxx.ets 207import { webview } from '@kit.ArkWeb'; 208 209@Entry 210@Component 211struct WebComponent { 212 controller: webview.WebviewController = new webview.WebviewController(); 213 214 build() { 215 Column() { 216 Web({ src: $rawfile("clipboard_event.html"), controller: this.controller }) 217 } 218 } 219} 220``` 221 222加载的html: 223 224```html 225<!--clipboard_event.html--> 226<!DOCTYPE html> 227<html lang="zh"> 228<head> 229 <meta charset="UTF-8"> 230 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 231 <title>Clipboard Event demo</title> 232 <style> 233 .output { 234 margin-top: 20px; 235 border: 1px solid #ccc; 236 padding: 10px; 237 max-width: 400px; 238 } 239 </style> 240</head> 241<body> 242<h2>Clipboard Event监听示例</h2> 243<textarea id="inputArea" rows="4" cols="50" placeholder="在这里输入文本,尝试复制和粘贴..."></textarea> 244 245<div class="output" id="output"> 246 <h3>输出内容:</h3> 247 <p id="resultText">没有复制或粘贴内容。</p> 248</div> 249 250<script> 251 const inputArea = document.getElementById('inputArea'); 252 const resultText = document.getElementById('resultText'); 253 254 // 监听复制事件 255 inputArea.addEventListener('copy', (event) => { 256 const selection = document.getSelection(); 257 const copiedText = selection.toString() + "(复制自ArkWeb)" 258 event.clipboardData.setData("text/plain", copiedText); 259 event.preventDefault(); 260 resultText.textContent = `复制的内容: "${copiedText}"`; 261 }); 262 263 // 监听粘贴事件 264 inputArea.addEventListener('paste', (event) => { 265 const pastedData = event.clipboardData.getData('text'); 266 resultText.textContent = `粘贴的内容: "${pastedData}"`; 267 }); 268 269 // 监听剪切事件 270 inputArea.addEventListener('cut', (event) => { 271 const selection = document.getSelection(); 272 const cutText = selection.toString() + "(剪切自ArkWeb)" 273 event.clipboardData.setData("text/plain", cutText); 274 selection.deleteFromDocument(); 275 event.preventDefault(); 276 resultText.textContent = `剪切的内容: "${cutText}"`; 277 }); 278</script> 279</body> 280</html> 281``` 282 283 284 285## 设置剪贴板复制范围选项 286 287开发者可以通过设置Web组件的[copyOptions](../reference/apis-arkweb/arkts-basic-components-web-attributes.md#copyoptions11)属性,来指定Web组件上剪贴板复制的范围。可以指定的选项有:CopyOptions.None(不支持复制)、CopyOptions.InApp(支持应用内复制)以及CopyOptions.LocalDevice(支持设备内复制)。默认值为:CopyOptions.LocalDevice,即默认支持设备内部的复制。 288 289```ts 290// xxx.ets 291import { webview } from '@kit.ArkWeb'; 292 293@Entry 294@Component 295struct WebComponent { 296 controller: webview.WebviewController = new webview.WebviewController(); 297 @State copyOption: CopyOptions = CopyOptions.LocalDevice; 298 299 build() { 300 Column() { 301 Web({ src: $rawfile("copyOptions.html"), controller: this.controller }) 302 .copyOptions(this.copyOption) 303 } 304 } 305} 306``` 307 308加载的html: 309 310```html 311<!--copyOptions.html--> 312<!DOCTYPE html> 313<html lang="zh"> 314<head> 315 <meta charset="UTF-8"> 316 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 317 <title>Clipboard CopyOption demo</title> 318</head> 319<body> 320<h2>Clipboard CopyOption示例</h2> 321<textarea id="inputArea"></textarea> 322</body> 323</html> 324``` 325