★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公眾號:山青詠芝(MaoistLearning)
➤部落格園地址:為敢技術(https://www.cnblogs.com/strengthen/ )
➤GitHub地址:https://github.com/strengthen
➤原文地址:https://www.cnblogs.com/strengthen/p/18475706
➤如果連結不是為敢技術的部落格園地址,則可能是爬取作者的文章。
➤原文已修改更新!強烈建議點選原文地址閱讀!支援作者!支援原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
頁面載入是Web元件的基本功能。根據頁面載入資料來源可以分為三種常用場景,包括載入網路頁面、載入本地頁面、載入HTML格式的富文字資料。
頁面載入過程中,若涉及網路資源獲取,需要配置ohos.permission.INTERNET網路訪問許可權。
載入網路頁面
開發者可以在Web元件建立時,指定預設載入的網路頁面 。在預設頁面載入完成後,如果開發者需要變更此Web元件顯示的網路頁面,可以透過呼叫loadUrl()介面載入指定的網頁。Web元件的第一個引數變數src不能透過狀態變數(例如:@State)動態更改地址,如需更改,請透過loadUrl()重新載入。
在下面的示例中,在Web元件載入完“www.example.com”頁面後,開發者可透過loadUrl介面將此Web元件顯示頁面變更為“www.example1.com”。
// xxx.ets import { webview } from '@kit.ArkWeb'; import { BusinessError } from '@kit.BasicServicesKit'; @Entry @Component struct WebComponent { controller: webview.WebviewController = new webview.WebviewController(); build() { Column() { Button('loadUrl') .onClick(() => { try { // 點選按鈕時,透過loadUrl,跳轉到www.example1.com this.controller.loadUrl('www.example1.com'); } catch (error) { let e: BusinessError = error as BusinessError; console.error(`ErrorCode: ${e.code}, Message: ${e.message}`); } }) // 元件建立時,載入www.example.com Web({ src: 'www.example.com', controller: this.controller}) } } }
載入本地頁面
將本地頁面檔案放在應用的rawfile目錄下,開發者可以在Web元件建立的時候指定預設載入的本地頁面 ,並且載入完成後可透過呼叫loadUrl()介面變更當前Web元件的頁面。
在下面的示例中展示載入本地頁面檔案的方法:
-
將資原始檔放置在應用的resources/rawfile目錄下。
圖1 資原始檔路徑
-
應用側程式碼。
// xxx.ets import { webview } from '@kit.ArkWeb'; import { BusinessError } from '@kit.BasicServicesKit'; @Entry @Component struct WebComponent { controller: webview.WebviewController = new webview.WebviewController(); build() { Column() { Button('loadUrl') .onClick(() => { try { // 點選按鈕時,透過loadUrl,跳轉到local1.html this.controller.loadUrl($rawfile("local1.html")); } catch (error) { let e: BusinessError= error as BusinessError; console.error(`ErrorCode: ${e.code}, Message: ${e.message}`); } }) // 元件建立時,透過$rawfile載入本地檔案local.html Web({ src: $rawfile("local.html"), controller: this.controller }) } } }
-
local.html頁面程式碼。
<!-- local.html --> <!DOCTYPE html> <html> <body> <p>Hello World</p> </body> </html>
-
local1.html頁面程式碼。
<!-- local1.html --> <!DOCTYPE html> <html> <body> <p>This is local1 page</p> </body> </html>
載入HTML格式的文字資料
Web元件可以透過loadData()介面實現載入HTML格式的文字資料。當開發者不需要載入整個頁面,只需要顯示一些頁面片段時,可透過此功能來快速載入頁面。
// xxx.ets import { webview } from '@kit.ArkWeb'; import { BusinessError } from '@kit.BasicServicesKit'; @Entry @Component struct WebComponent { controller: webview.WebviewController = new webview.WebviewController(); build() { Column() { Button('loadData') .onClick(() => { try { // 點選按鈕時,透過loadData,載入HTML格式的文字資料 this.controller.loadData( "<html><body bgcolor=\"white\">Source:<pre>source</pre></body></html>", "text/html", "UTF-8" ); } catch (error) { let e: BusinessError= error as BusinessError; console.error(`ErrorCode: ${e.code}, Message: ${e.message}`); } }) // 元件建立時,載入www.example.com Web({ src: 'www.example.com', controller: this.controller }) } } }
動態建立Web元件
支援命令式建立Web元件,這種方式建立的元件不會立即掛載到元件樹,即不會對使用者呈現(元件狀態為Hidden和InActive),開發者可以在後續使用中按需動態掛載。後臺啟動的Web例項不建議超過200個。
// 載體Ability // EntryAbility.ets import { createNWeb } from "../pages/common" onWindowStageCreate(windowStage: window.WindowStage): void { windowStage.loadContent('pages/Index', (err, data) => { // 建立Web動態元件(需傳入UIContext),loadContent之後的任意時機均可建立 createNWeb("https://www.example.com", windowStage.getMainWindowSync().getUIContext()); if (err.code) { return; } }); }
// 建立NodeController // common.ets import { webview } from '@kit.ArkWeb'; import { NodeController, BuilderNode, Size, FrameNode, UIContext } from '@kit.ArkUI'; // @Builder中為動態元件的具體元件內容 // Data為入參封裝類 class Data{ url: string = "https://www.example.com"; controller: WebviewController = new webview.WebviewController(); } @Builder function WebBuilder(data:Data) { Column() { Web({ src: data.url, controller: data.controller }) .width("100%") .height("100%") } } let wrap = wrapBuilder<Data[]>(WebBuilder); // 用於控制和反饋對應的NodeContainer上的節點的行為,需要與NodeContainer一起使用 export class myNodeController extends NodeController { private rootnode: BuilderNode<Data[]> | null = null; // 必須要重寫的方法,用於構建節點數、返回節點掛載在對應NodeContainer中 // 在對應NodeContainer建立的時候呼叫、或者透過rebuild方法呼叫重新整理 makeNode(uiContext: UIContext): FrameNode | null { console.log(" uicontext is undefined : "+ (uiContext === undefined)); if (this.rootnode != null) { // 返回FrameNode節點 return this.rootnode.getFrameNode(); } // 返回null控制動態元件脫離繫結節點 return null; } // 當佈局大小發生變化時進行回撥 aboutToResize(size: Size) { console.log("aboutToResize width : " + size.width + " height : " + size.height ) } // 當controller對應的NodeContainer在Appear的時候進行回撥 aboutToAppear() { console.log("aboutToAppear") } // 當controller對應的NodeContainer在Disappear的時候進行回撥 aboutToDisappear() { console.log("aboutToDisappear") } // 此函式為自定義函式,可作為初始化函式使用 // 透過UIContext初始化BuilderNode,再透過BuilderNode中的build介面初始化@Builder中的內容 initWeb(url:string, uiContext:UIContext, control:WebviewController) { if(this.rootnode != null) { return; } // 建立節點,需要uiContext this.rootnode = new BuilderNode(uiContext) // 建立動態Web元件 this.rootnode.build(wrap, { url:url, controller:control }) } } // 建立Map儲存所需要的NodeController let NodeMap:Map<string, myNodeController | undefined> = new Map(); // 建立Map儲存所需要的WebViewController let controllerMap:Map<string, WebviewController | undefined> = new Map(); // 初始化需要UIContext 需在Ability獲取 export const createNWeb = (url: string, uiContext: UIContext) => { // 建立NodeController let baseNode = new myNodeController(); let controller = new webview.WebviewController() ; // 初始化自定義Web元件 baseNode.initWeb(url, uiContext, controller); controllerMap.set(url, controller) NodeMap.set(url, baseNode); } // 自定義獲取NodeController介面 export const getNWeb = (url : string) : myNodeController | undefined => { return NodeMap.get(url); }
// 使用NodeController的Page頁 // Index.ets import { getNWeb } from "./common" @Entry @Component struct Index { build() { Row() { Column() { // NodeContainer用於與NodeController節點繫結,rebuild會觸發makeNode // Page頁透過NodeContainer介面繫結NodeController,實現動態元件頁面顯示 NodeContainer(getNWeb("https://www.example.com")) .height("90%") .width("100%") } .width('100%') } .height('100%') } }