Swift中如何仅显示WebView的指定内容区域?
在Swift的WKWebView中仅显示指定内容区域的方案
嘿,这个需求我之前做轻量阅读器的时候刚好实现过,要把WKWebView里的网页“瘦身”,只留核心内容,其实核心思路就是通过注入脚本(CSS/JS)来操作网页DOM,下面给你几个实用的方案,针对维基百科这类网站特别好用:
方法1:注入CSS隐藏不需要的元素
这是最直观的方式——找到你想隐藏的元素(比如侧边栏、导航栏)的CSS选择器,然后给它们加上display: none的样式。
步骤:
- 先通过浏览器的开发者工具(比如Safari的Web检查器)定位目标元素的选择器,比如维基百科的侧边栏是
#mw-panel,顶部导航是#mw-head; - 在WKWebView加载完成后,注入自定义CSS代码。
代码示例:
首先设置WKWebView的navigationDelegate,然后在didFinishNavigation方法里执行脚本:
import WebKit class ViewController: UIViewController, WKNavigationDelegate { var webView: WKWebView! override func viewDidLoad() { super.viewDidLoad() let config = WKWebViewConfiguration() webView = WKWebView(frame: view.bounds, configuration: config) webView.navigationDelegate = self view.addSubview(webView) // 加载维基百科页面 if let url = URL(string: "https://zh.wikipedia.org/wiki/Swift_(程式語言)") { webView.load(URLRequest(url: url)) } } func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { // 注入CSS隐藏不需要的元素 let hideCSS = """ #mw-panel, #mw-head, #footer, .mw-editsection { display: none !important; } #content { margin: 0 auto; width: 100% !important; padding: 16px; } """ let injectCSSScript = "var style = document.createElement('style'); style.innerHTML = '\(hideCSS)'; document.head.appendChild(style);" webView.evaluateJavaScript(injectCSSScript) { result, error in if let error = error { print("注入CSS失败:\(error.localizedDescription)") } } } }
方法2:用JavaScript提取核心内容替换整个页面
如果想更彻底,直接把网页的核心内容提取出来,替换掉整个body的内容,这样WebView里就只剩你要的部分了。比如维基百科的核心内容都在#content容器里,我们可以直接把这个容器的内容拿出来作为页面主体。
代码示例:
在didFinishNavigation里替换成这段脚本:
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { // 提取核心内容并替换页面 let extractContentScript = """ var content = document.getElementById('content'); if (content) { document.body.innerHTML = content.outerHTML; // 再加一点自定义样式优化显示 document.body.style.margin = '0'; document.body.style.padding = '16px'; } """ webView.evaluateJavaScript(extractContentScript) { result, error in if let error = error { print("提取内容失败:\(error.localizedDescription)") } } }
方法3:提前注入脚本(WKUserScript)
如果你的APP只针对固定几个网站(比如只做维基百科阅读器),可以提前把脚本注入到WKWebView的配置里,这样页面加载的时候会自动执行,不用等加载完成再处理,体验更流畅。
代码示例:
override func viewDidLoad() { super.viewDidLoad() let config = WKWebViewConfiguration() // 创建要注入的脚本 let hideScriptSource = """ // 等待DOM加载完成后执行 document.addEventListener('DOMContentLoaded', function() { var content = document.getElementById('content'); if (content) { document.body.innerHTML = content.outerHTML; document.body.style.margin = '0'; document.body.style.padding = '16px'; } }); """ // 创建WKUserScript,设置在documentEnd时注入(DOM已构建完成) let userScript = WKUserScript(source: hideScriptSource, injectionTime: .atDocumentEnd, forMainFrameOnly: true) config.userContentController.addUserScript(userScript) webView = WKWebView(frame: view.bounds, configuration: config) view.addSubview(webView) // 加载页面 if let url = URL(string: "https://zh.wikipedia.org/wiki/Swift_(程式語言)") { webView.load(URLRequest(url: url)) } }
一些注意事项
- 选择器适配:不同网站的DOM结构不一样,一定要先用浏览器检查器确认元素的ID或类名;
- 动态内容处理:如果页面是JS动态渲染的,可能需要等待一段时间再执行脚本,或者监听
DOMNodeInserted这类事件; - 错误处理:执行脚本时要处理可能的错误(比如找不到目标元素),避免影响用户体验;
- 样式优化:移除多余元素后,记得调整核心内容的样式(比如宽度、内边距),让它更适配手机屏幕。
内容的提问来源于stack exchange,提问作者Yo19
相关产品推荐
相关产品推荐

