获取Whooshkaa播放列表链接的WKWebView内容高度异常问题
解决WKWebView获取Whooshkaa播放列表完整内容高度的问题
你遇到的核心问题其实是页面动态内容加载延迟——didFinish navigation触发时,Whooshkaa的播放列表还没完全渲染出来,所以你拿到的document.body.offsetHeight只是页面初始的占位高度(200px),而非完整播放列表的实际高度。下面给你几个可行的解决方案:
方案1:等待动态内容稳定后再获取高度
通过注入JavaScript代码,监听页面内容的变化,直到高度不再更新,再通知原生代码获取最终高度。比如用定时器循环检查,或者用MutationObserver监听DOM变化:
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { // 注入JS代码,等待内容加载稳定 let jsScript = """ function getStableHeight() { return new Promise((resolve) => { let lastHeight = 0; const checkTimer = setInterval(() => { const currentHeight = document.documentElement.scrollHeight; // 连续两次高度一致,说明内容加载完成 if (currentHeight === lastHeight) { clearInterval(checkTimer); resolve(currentHeight); } lastHeight = currentHeight; }, 200); // 最多等待5秒,防止无限等待 setTimeout(() => { clearInterval(checkTimer); resolve(document.documentElement.scrollHeight); }, 5000); }); } getStableHeight(); """ webView.evaluateJavaScript(jsScript) { [weak self] (height, error) in guard let height = height as? CGFloat, error == nil else { print("获取高度失败: \(error?.localizedDescription ?? "未知错误")") return } // 这里拿到的就是完整内容高度,更新你的自定义View框架 self?.updateCustomViewFrame(with: height) } }
方案2:直接定位播放列表容器获取高度
打开网页检查元素,找到Whooshkaa播放列表对应的容器元素(比如带有特定class/id的<div>),直接获取该容器的高度,而非整个body的高度。假设播放列表容器的class是whooshkaa-playlist-container,可以这么写:
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { webView.evaluateJavaScript("document.querySelector('.whooshkaa-playlist-container').offsetHeight") { [weak self] (height, error) in guard let height = height as? CGFloat, error == nil else { // 如果找不到目标元素,降级获取整个页面高度 webView.evaluateJavaScript("document.documentElement.scrollHeight") { (fallbackHeight, _) in if let fallbackHeight = fallbackHeight as? CGFloat { self?.updateCustomViewFrame(with: fallbackHeight) } } return } self?.updateCustomViewFrame(with: height) } }
方案3:优化scrollView内容Size监听
你之前尝试过监听contentSize,但可能没处理初始值的问题。可以在WKWebView初始化时就添加观察者,忽略初始的200px,只处理高度更新后的有效值:
override func viewDidLoad() { super.viewDidLoad() // 给webView的scrollView添加contentSize观察者 webView.scrollView.addObserver(self, forKeyPath: "contentSize", options: .new, context: nil) } override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { if keyPath == "contentSize", let scrollView = object as? UIScrollView { let contentHeight = scrollView.contentSize.height // 忽略初始的200px占位高度,只处理实际内容高度 if contentHeight > 200 { updateCustomViewFrame(with: contentHeight) // 可以选择移除观察者,避免重复触发 scrollView.removeObserver(self, forKeyPath: "contentSize") } } } deinit { // 记得移除观察者,避免内存泄漏 webView.scrollView.removeObserver(self, forKeyPath: "contentSize") }
关键提醒:
Whooshkaa的播放列表是异步加载的动态内容,didFinish navigation仅表示页面初始HTML加载完成,而非所有动态资源渲染完毕。所以必须等内容完全加载稳定,或者直接定位到播放列表容器,才能拿到准确的高度值。
内容的提问来源于stack exchange,提问作者Canh Tran
相关产品推荐
相关产品推荐

