WebView横屏模式下JavascriptInterface未生效无法监听滚动事件如何解决
问题根因
横屏下滚动监听失效有两个核心诱因:
MyWebViewClient的onPageFinished方法中,恢复滚动位置的分支未调用父类方法,导致WebView上下文状态异常- JS侧的
findSmallElementOnScreen方法存在死循环风险:横屏下页面布局变化,如果所有可见元素高度都大于你设定的1024px阈值,while循环会无限执行,永远不会返回元素,也就不会触发onScrollPositionChange回调
修复方案
1. 修复Android端代码
首先补全onPageFinished的父类调用,确保所有场景下WebView状态都能正确初始化:
private class MyWebViewClient extends WebViewClient { public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); // 移到方法最开头,全场景执行父类逻辑 if (initialScrollElement != null) { view.postDelayed(new Runnable() { @Override public void run() { StringBuilder buf=new StringBuilder("javascript:scrollToPosition('"+initialScrollElement+"','"+initialScrollMargin+"')"); Log.d("MyWebViewClient", "returned string:"+buf.toString()); webview.loadUrl(buf.toString()); initialScrollElement = null; } }, 300); } else { if (!url.contains("#") && !hashTag.isEmpty()) { String myurl = url + hashTag; webview.loadUrl(myurl); } } } }
如果不需要在横竖屏切换时重建页面,建议给对应Activity增加配置变更声明,避免不必要的销毁重建,在AndroidManifest.xml的对应Activity标签下添加:
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
2. 修复JS侧代码
修改findSmallElementOnScreen方法,增加循环限制和适配逻辑,避免死循环:
var findSmallElementOnScreen = function() { // 尺寸阈值适配当前屏幕高度,横屏场景也能覆盖 var SIZE_LIMIT = Math.max(1024, window.innerHeight * 0.8); var MAX_TRIES = 20; // 最多探测20次,避免无限循环 var elem = undefined; var offsetY = 0; var tryCount = 0; while (!elem && tryCount < MAX_TRIES) { var e = document.elementFromPoint(100, offsetY); if (!e) break; // 超出可视区域直接跳出 if (e.getBoundingClientRect().height < SIZE_LIMIT) { elem = e; } else { offsetY += 50; } tryCount++; } // 探测不到符合要求的元素时 fallback 到body,保证逻辑不中断 if (!elem) elem = document.body; return elem; };
同时给上报逻辑增加容错判断,避免JS接口不存在时抛出异常:
var reportScrollPosition = function() { var elem = findSmallElementOnScreen(); // 增加接口存在校验,避免切换过程中报错 if (elem && window.WebScrollListener) { var selector = getCssSelector(elem); var offset = elem.getBoundingClientRect().top; WebScrollListener.onScrollPositionChange(selector, offset); } }
验证步骤
修改完成后按以下流程验证功能:
- 竖屏滚动到任意位置,切换横屏,确认滚动位置正确恢复
- 横屏下滚动页面,查看Logcat是否有
WebScrollListener的日志输出 - 横屏切换回竖屏,确认滚动位置也能正常恢复
内容的提问来源于stack exchange,提问作者Lorna from Perth
相关产品推荐
相关产品推荐

