HarmonyOS 鸿蒙Next中web组件嵌套H5页面,页面可滑动,但调用web组件的scrollTo(0,0)无效
HarmonyOS 鸿蒙Next中web组件嵌套H5页面,页面可滑动,但调用web组件的scrollTo(0,0)无效
web组件嵌套了一个H5页面(H5的代码看不到),页面是可以上下滑动的。想做一个点击状态栏页面回到顶部,先监听状态栏点击事件,然后调用web组件的scrollTo(0,0)回顶,然而没有效果。把scrollTo换成refresh,页面是可以刷新的,说明整体逻辑没问题,应该是web嵌套了H5页面,H5在滚动,但web并没有滚动。请问该如何实现web和H5一起滚动?或者说scrollTo该如何起作用?
监听部分代码:
private subscribeInfo: commonEventManager.CommonEventSubscribeInfo = {
events: [
'usual.event.CLICK_STATUSBAR'
]
};
public registerPowerSaveModeChange(): void {
let mSubscriber = commonEventManager.createSubscriberSync(this.subscribeInfo);
if (mSubscriber === null) {
console.info(`create subscriber errot!`);
return;
}
commonEventManager.subscribe(mSubscriber,
async (err: BusinessError, data: commonEventManager.CommonEventData) => {
if (err) {
console.info(`Can't handle common event, err: ${err.code}, err: ${err.message}`);
return;
}
// 触发回顶
this.controller.scrollTo(0, 0, 500);
console.info('Publish success');
});
}
aboutToAppear(): void {
this.registerPowerSaveModeChange()
}
web部分代码:
Web({ src: this.Url, controller: this.controller })
.backgroundColor(Color.Transparent)
.height('100%')
.width('100%')
.domStorageAccess(true)
.javaScriptAccess(true)
.fileAccess(false)
.darkMode(WindowManager.getInstance().isDarkMode() ? WebDarkMode.On : WebDarkMode.Off)
.forceDarkAccess(WindowManager.getInstance().isDarkMode() ? true : false)
.geolocationAccess(false)
.onProgressChange((event?: ProgressResultObject) => {
if (event) {
Logger.d(TAG, 'newProgress: %s', event.newProgress);
this.progress = event.newProgress;
}
})
.onPageEnd((event?: PageEndCallbackObject) => {
Logger.i(TAG, 'onPageEnd');
this.isLoading = false;
})
更多关于HarmonyOS 鸿蒙Next中web组件嵌套H5页面,页面可滑动,但调用web组件的scrollTo(0,0)无效的实战教程也可以访问 https://www.itying.com/category-93-b0.html
import { webview } from '@kit.ArkWeb'
import { webCommonPermissionHelper } from '../common/util/WebCommonPermissionHelper'
@Entry
@Component
struct WebTestPage {
@State controller: webview.WebviewController = new webview.WebviewController()
@State url: string | Resource =
'https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-webview-webviewcontroller'
build() {
Scroll() {
Column() {
Button('滚动测试').onClick((event: ClickEvent) => {
this.controller.scrollTo(0, 0, 500);
})
Web({
src: this.url,
controller: this.controller,
})
.layoutWeight(1)
.width('100%')
.height('100%')
.onPermissionRequest((request: OnPermissionRequestEvent) => {
webCommonPermissionHelper.onWebPermissionRequest(request)
})
.onGeolocationShow(async (event: OnGeolocationShowEvent) => {
AlertDialog.show({ message: JSON.stringify(event, null, 2) })
})
}
// .height('100%')
.width('100%')
}
.height('100%')
.width('100%')
}
}
更多关于HarmonyOS 鸿蒙Next中web组件嵌套H5页面,页面可滑动,但调用web组件的scrollTo(0,0)无效的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
楼主好,Web组件内部H5页面的滚动属于WebView独立滚动链,与原生Scroll组件的滚动控制没有联动。
直接调用Web组件的scrollTo仅作用于原生容器层级,无法穿透到H5内部滚动视图!!
你可以通过Web组件控制器执行JavaScript代码控制H5页面内容滚动:
// 修改回顶逻辑触发JS脚本执行
this.controller.runJavaScript('window.scrollTo(0,0);', (error, result) => {
if (!error) {
console.info('H5 scrollTo executed');
}
});
或者通过动态获取H5页面高度实现原生滚动联动也行
Web({
src: this.Url,
controller: this.controller
})
.onPageEnd(e => {
// 注入JS获取文档高度
this.controller.runJavaScript(
'document.documentElement.scrollHeight.toString()',
(error, result) => {
if (!error) {
this.webHeight = result + 'px'; // 动态设置Web组件高度
}
}
)
})
.height(this.webHeight) // 绑定动态高度
1.通过nestedScroll协调内外滚动层级
Scroll() {
Web({
controller: this.webController,
src: $rawfile('index.html')
})
.nestedScroll({
scrollForward: NestedScrollMode.SELF_FIRST, // 先处理Web内部滚动
scrollBackward: NestedScrollMode.SELF_FIRST
})
}
.nestedScroll({
scrollForward: NestedScrollMode.PARENT_FIRST, // Scroll容器处理剩余滚动
scrollBackward: NestedScrollMode.PARENT_FIRST
})
2.通过JS注入获取H5内容实际高度
Web({
controller: this.webController,
src: $rawfile('index.html')
})
.javaScriptOnDocumentStart(`
window.addEventListener('load', () => {
const height = document.documentElement.scrollHeight;
HarmonyOS.postMessage({height: height});
});
`)
.onMessage((event) => {
this.webHeight = event.height;
})
.layoutMode(WebLayoutMode.FIT_CONTENT) // 启用自适应布局
- 通过JS 进行H5 页面滚动到顶部
this.webController.runJavaScript('window.scrollTo(0,0)')
你还可以通过js来让页面滚动到顶部:
// 调用JavaScript执行页面滚动到顶部
this.webController.runJavaScript('window.scrollTo(0, 0);')
.then(() => {
console.info('Successfully scrolled to top');
})
.catch((error: Error) => {
console.error('Failed to scroll to top: ' + error.message);
});
const js = `window.scrollTo({
top: 0,
behavior: 'smooth'
});`
this.controller.runJavaScript(js)
建议你现在pc浏览器中调试一下你的网页,调用js代码 ** window.scrollTo(0, 0);** 看看有没有效果吧!
在HarmonyOS鸿蒙Next中,Web组件嵌套H5页面时,调用scrollTo(0,0)无效可能是由于Web组件与H5页面的滚动机制不同步导致的。鸿蒙的Web组件基于系统级实现,而H5页面使用浏览器自身的滚动机制。需要确保在Web组件加载完成后,通过执行JavaScript代码来触发H5页面的滚动重置,例如使用webview.executeJs(“window.scrollTo(0,0)”)。
在HarmonyOS Next中,Web组件的scrollTo方法只能控制Web组件自身的滚动,而无法控制嵌套H5页面的内部滚动。这是因为H5页面有自己的滚动机制,独立于Web组件。
解决方案建议:
- 通过JavaScript注入方式控制H5页面滚动:
this.controller.runJavaScript('window.scrollTo(0,0)');
- 如果H5页面使用了div等元素滚动,需要获取对应元素:
this.controller.runJavaScript('document.getElementById("scrollContainer").scrollTo(0,0)');
-
确保Web组件已加载完成后再执行JS代码,可以在onPageEnd回调中设置标志位。
-
如果H5页面是自己开发的,建议在H5页面中监听消息:
// ArkTS侧
this.controller.postMessage('scrollToTop');
// H5侧
window.addEventListener('message', (e) => {
if(e.data === 'scrollToTop') {
window.scrollTo(0,0);
}
});
这种方法能更可靠地控制H5页面内部的滚动行为。