HarmonyOS鸿蒙Next中如何解决Web组件在嵌套如Scroll组件后,无法跟随页面整体滑动的问题
HarmonyOS鸿蒙Next中如何解决Web组件在嵌套如Scroll组件后,无法跟随页面整体滑动的问题
【问题现象】
在Scroll组件内嵌套使用Web组件和其他容器组件的组合时,如下:
Scroll() {
Row() {}
Web() {}
Row() {}
List() {}
}
Web组件显示不全或只能单独滚动,无法实现与Row、List等组件连为一个整体进行滚动。
【背景知识】
Web组件:
Web组件提供网页显示功能。
事件:
- onPageEnd:在页面加载完成时触发的回调,可以添加设置页面加载完成后的操作。
- runJavaScript:返回JavaScript脚本执行的结果,需要放在页面加载完成后,如onPageEnd。
- onFirstMeaningfulPaint:页面渲染完成时触发的回调,用法与onPageEnd类似。
- onGestureJudgeBegin:自定义手势判定,当绑定的手势被接受时触发自定义内容的回调。
属性:
layoutMode:用来设置Web的布局模式,包含两种:Web布局跟随系统(WebLayoutMode.NONE)和Web组件高度基于前端页面高度的自适应网页布局(WebLayoutMode.FIT_CONTENT)。
【定位思路】
从问题现象可以看出当前有两种状态:Web组件会单独滑动以及内容显示不全。
分析两种状态的原因:
- Web组件单独滑动是因为固定了组件的高度,且该高度小于内容高度;
- Web组件内容显示不全是因为在第1点的基础上禁止了Web的滑动。
所以问题的关键就在于如何控制Web组件的高度,让其可以适应内容,从而达到将Web变成一个完全展开的view。
【解决方案】
方法一:手动计算高度
在HTML文件中完成高度计算(watchWindowSize
函数)。
<!DOCTYPE html>
<html>
<body>
<p>
<h1>测试测试</h1>
<h2>测试测试</h2>
<h2>测试测试</h2>
</p>
</body>
<script type="text/javascript">
function watchWindowSize() {
var h = document.body.clientHeight;
return h;
}
</script>
</html>
然后通过runJavaScript将获取到的高度传入ArkTS页面中,并在onPageEnd回调中接收并设置webview的高度。
Web({ src: $rawfile('index.html'), controller: this.webviewController })
.javaScriptAccess(true) // 设置是否允许执行js脚本,默认为true
.onPageEnd(e => {
this.webviewController.runJavaScript( // 执行js脚本
'watchWindowSize()', (error, result) => {
this.webResult = result; // 获取js监听html返回的值
}
);
})
优化:考虑到onPageEnd是页面加载完回调,非页面渲染完成,这样可能会导致前后获取的高度不一致,可以用onFirstMeaningfulPaint替换onPageEnd在页面渲染完成时进行高度计算,不需要再监听HTML文件,同时加上对Web的系统手势进行限制,从而实现整体滑动。
Web({ src: $rawfile('index.html'), controller: this.webviewController })
.height(this.realHeight > 0 ? this.realHeight : 'auto') // 执行onFirstMeaningfulPaint回调获取组件高度,
.onFirstMeaningfulPaint(e => {
this.pageHeight = this.webviewController.getPageHeight();
this.realHeight = px2vp(this.pageHeight) // 单位转换
})
// 禁用Web的系统手势
.onGestureJudgeBegin((gestureInfo: GestureInfo, event: BaseGestureEvent) => {
if (gestureInfo.isSystemGesture) {
return GestureJudgeResult.REJECT
} else {
return GestureJudgeResult.CONTINUE
}
})
方法二:Web自适应
通过设置layoutMode属性为WebLayoutMode.FIT_CONTENT让Web完成自适应内容高度。
// 网页内容过宽或者过长时需要制定设置为RenderMode.SYNC_RENDER
Web({ src: $rawfile('index.html'), controller: this.webviewController, renderMode: RenderMode.SYNC_RENDER })
.width('100%')
.height('100%')
.layoutMode(WebLayoutMode.FIT_CONTENT) // 设置web组件高度给予前端页面高度进行自适应
.overScrollMode(OverScrollMode.NEVER) // 关闭过界回弹效果
.zoomAccess(false) // 关闭手势缩放
运行代码可以发现已经实现了Web组件跟随其他组件一起整体滑动:
【总结】
方法一较贴近底层实现,用最简单直接的方式获取页面高度并赋值给Web组件,容易想到但代码量偏多且复杂度高,出错率高;
相比之下方法二则更简单实用,同时支持页面变化(点击进入新的页面),不支持瀑布流网页(下拉到底部加载更多)。
更多关于HarmonyOS鸿蒙Next中如何解决Web组件在嵌套如Scroll组件后,无法跟随页面整体滑动的问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于HarmonyOS鸿蒙Next中如何解决Web组件在嵌套如Scroll组件后,无法跟随页面整体滑动的问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next中,Web组件嵌套在Scroll组件后无法跟随页面整体滑动的问题可以通过以下两种方法解决:
方法一:手动计算高度
- 在HTML文件中使用
watchWindowSize
函数计算页面高度。 - 通过
runJavaScript
将高度传入ArkTS页面,并在onFirstMeaningfulPaint
回调中设置Web组件高度。 - 禁用Web的系统手势,确保整体滑动。
方法二:Web自适应
- 设置Web组件的
layoutMode
属性为WebLayoutMode.FIT_CONTENT
,使Web组件高度自适应前端页面高度。 - 关闭过界回弹效果和手势缩放,确保Web组件与其他组件一起整体滑动。
方法一代码量较多且复杂,方法二更简单实用,但不支持瀑布流网页。