1# 使用Web组件的手势与应用交互 2<!--Kit: ArkWeb--> 3<!--Subsystem: Web--> 4<!--Owner: @zourongchun--> 5<!--Designer: @zhufenghao--> 6<!--Tester: @ghiker--> 7<!--Adviser: @HelloCrease--> 8在移动端或支持触控的Web应用中,用户通过触摸屏与页面交互,Web组件支持了常见的手势识别,例如长按、滑动、点击等,以支持丰富的用户交互体验。 9## ArkWeb手势识别 10ArkWeb接收ArkUI的[触摸事件](../ui/arkts-interaction-development-guide-touch-screen.md#触摸事件),并识别出手势(触摸事件的分发策略详见[交互基础机制说明](../ui/arkts-interaction-basic-principles.md))。ArkWeb手势符合W3C标准:Touch Events、UI Events、Pointer Events。 11 12常见事件识别说明: 13| 手势事件 | 触发条件 | 14| --- | --- | 15| Tap | 按下并抬起时触发,且间隔较短未触发长按。 | 16| LongPress | 按下且不移动,经过一段延迟后触发。 | 17| ScrollBegin | 滚动开始时触发。 | 18| ScrollUpdate | 滚动时触发,包括抛滑和拖滑。手指未离开屏幕时的滚动为拖滑;若手指离开屏幕时带有速度,离手后页面继续滚动,被称为抛滑。| 19| ScrollEnd | 滚动结束时触发。 | 20| FlingStart| 滚动过程中手指抬起,且抬手速度足够快,触发了抛滑。| 21| FlingCancel| 取消抛滑时触发。 | 22| PinchBegin | 捏合开始时触发。 | 23| PinchUpdate | 捏合过程中触发。 | 24| PinchEnd | 捏合结束时触发。 | 25 26## ArkWeb手势与ArkUI手势 27ArkUI提供了[手势绑定](../ui/arkts-gesture-events-binding.md),Web组件有独立的手势识别,因此需要区分两种手势: 28- ArkWeb手势:Web组件接收触摸事件自动生成的手势,这些手势作用于网页上。 29- ArkUI手势:Web组件作为通用组件会接收ArkUI手势,ArkUI手势并不直接作用于网页,而作用于Web组件上。 30 31以缩放为例说明两种手势的区别: 32- 在Web上使用双指捏合时,Web组件中的内容将会缩放。这是由于ArkWeb识别了Pinch事件并将其作用于网页上。 33- 使用三指捏合,Web组件本身会进行缩放。这是因为ArkWeb接收到ArkUI识别出的[PinchGesture](../ui/arkts-gesture-events-single-gesture.md#捏合手势pinchgesture),执行绑定的回调函数。同时,ArkWeb支持scale方法,能够调整Web组件的缩放比例。 34 35> **说明:** 36> 37> 该示例仅用于说明ArkUI手势和ArkWeb手势的区别,不建议使用此方法进行Web组件的缩放。 38```ts 39// xxx.ets 40import { webview } from '@kit.ArkWeb'; 41 42@Entry 43@Component 44struct Index { 45 @State scaleValue: number = 1; 46 @State pinchValue: number = 1; 47 controller: webview.WebviewController = new webview.WebviewController(); 48 49 build() { 50 Column() { 51 Web({ src: 'www.example.com', controller: this.controller }) 52 // 在组件上绑定缩放比例,可以通过修改缩放比例来实现组件的缩小或者放大 53 .scale({ x: this.scaleValue, y: this.scaleValue, z: 1 }) 54 .zoomAccess(true) 55 .gesture( 56 // 在组件上绑定三指触发的捏合手势 57 PinchGesture({ fingers: 3 }) 58 .onActionStart((event: GestureEvent|undefined) => { 59 console.info('Pinch start'); 60 }) 61 // 当捏合手势触发时,可以通过回调函数获取缩放比例,从而修改组件的缩放比例 62 .onActionUpdate((event: GestureEvent|undefined) => { 63 if(event){ 64 this.scaleValue = this.pinchValue * event.scale; 65 console.info('Pinch update'); 66 } 67 }) 68 .onActionEnd(() => { 69 this.pinchValue = this.scaleValue; 70 console.info('Pinch end'); 71 }) 72 ) 73 } 74 } 75} 76``` 77 78 79## Web组件的手势拦截 80- ArkUI手势 81 82 ArkWeb会消费部分ArkUI手势,例如[拖动手势](../ui/arkts-gesture-events-single-gesture.md#拖动手势pangesture),若希望自行处理这些手势而非由ArkWeb消费,可以参考ArkUI的[手势拦截](../ui/arkts-gesture-events-gesture-judge.md)。 83 84- ArkWeb手势 85 86 ArkWeb手势的生成需要Web组件接收触摸事件,有两种拦截方案: 87 1. 完全禁止触摸事件发送给Web组件,详见[触摸测试](../ui/arkts-interaction-basic-principles.md#触摸测试)。 88 2. 发送TouchCancel触摸事件给Web组件,详见[OH_ArkUI_TouchRecognizer_CancelTouch](../reference/apis-arkui/capi-native-gesture-h.md#函数)。 89 90 91## 常见问题 92 93### 如何禁用缩放手势 94Web组件提供了接口[zoomAccess](../reference/apis-arkweb/arkts-basic-components-web-attributes.md#zoomaccess),控制是否可以缩放。网页上有user-scalable属性也会影响缩放。详见[使用Web组件管理网页缩放](web-scale-zoom.md)。 95### Web组件中如何通过手势滑动返回上一个Web页面 96 97**解决措施** 98 99通过重写onBackPress函数来自定义返回逻辑,使用WebviewController判断是否返回上一个Web页面。 100 101**示例代码** 102 103```ts 104import web_webview from '@ohos.web.webview'; 105 106@Entry 107@Component 108struct Index { 109 controller: web_webview.WebviewController = new web_webview.WebviewController(); 110 111 build() { 112 Column() { 113 Web({ src: 'https://www.example.com', controller: this.controller })//需要手动替换为真实网站 114 } 115 } 116 117 onBackPress() { 118 // 当前页面是否可前进或者后退给定的step步(-1),正数代表前进,负数代表后退 119 if (this.controller.accessStep(-1)) { 120 this.controller.backward(); // 返回上一个web页 121 // 执行用户自定义返回逻辑 122 return true 123 } else { 124 // 执行系统默认返回逻辑,返回上一个page页 125 return false 126 } 127 } 128} 129``` 130 131### 为什么Web加载后网页无法交互? 132 133网页可能基于其他平台的User-Agent进行判断。为解决此问题,可以在Web组件中设置自定义User-Agent,例如: 134 135```ts 136import { webview } from '@kit.ArkWeb' 137 138@Entry 139@Component 140struct Index { 141 private webController: webview.WebviewController = new webview.WebviewController() 142 build(){ 143 Column() { 144 Web({ 145 src: 'https://www.example.com', 146 controller: this.webController, 147 }).onControllerAttached(() => { 148 // 自定义User-Agent 149 let customUA = 'Mozilla/5.0 (Phone; Android; OpenHarmony 5.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Mobile Safari/537.36' 150 this.webController.setCustomUserAgent(customUA) 151 }) 152 } 153 } 154} 155```