You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

获取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:55:05