如何在WKWebView中注入多个用户脚本以获得暗模式效果?
How to inject multiple user scripts in WKWebView to obtain darkmode effect?
我已经使用这个很棒的 tutorial.
的源代码在网站 html 页面上成功获得了随机 HTML 的暗模式效果
我上传这些照片是为了更好地解释我得到的东西。
我正在尝试在 WKWebView 上获得相同的内容。
HTML 是从 API 加载的,所以我使用 WKWebView.loadHTMLString 方法。
对于此示例,演示 HTML 保存在 Xcode 项目的文件中。
此外,我还在 Xcode 中添加了 2 个 javascript 文件:darkmode.min.js(这是库)和 darkmode-options.js(底部切换的位置和文本标签页面)。
我认为我没有使用 WKUserScript 正确注入 2 个脚本。显然 darkmode.min.js 必须在 darkmode-options.js 之前加载。这就是为什么我使用 WKUserScriptInjectionTime.atDocumentStart 和 WKUserScriptInjectionTime.atDocumentEnd.
此外,当我在控制台中打印 HTML 的查看源代码时,它不显示已插入的脚本。
private func initWebView() {
let html = self.demoHTML
let jsLibrary = self.darkModeLibraryJS
let jsOptions = self.darkModeOptionsJS
let webConfiguration = WKWebViewConfiguration()
let contentController = WKUserContentController()
// Libray script an document start
let userScript = WKUserScript(source: jsLibrary, injectionTime: WKUserScriptInjectionTime.atDocumentStart, forMainFrameOnly: false)
contentController.addUserScript(userScript)
// Options script and document end
let optionsScript = WKUserScript(source: jsOptions, injectionTime: WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: false)
contentController.addUserScript(optionsScript)
webConfiguration.userContentController = contentController
self.webview = WKWebView(frame: CGRect.zero, configuration: webConfiguration)
self.webview?.navigationDelegate = self
self.view.addSubview(webview!)
self.webview!.loadHTMLString(html, baseURL: nil)
self.webview!.fillSuperview() // after view has been added as subview
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.chechHTML()
}
private func chechHTML() {
let script = "document.documentElement.outerHTML.toString()"
self.webview?.evaluateJavaScript(script, completionHandler: { (html, error) in
if html != nil {
print("❌: check html response", html ?? "")
}
if error != nil {
print("❌: check html with error", error ?? "")
}
})
}
项目上传于 github:https://github.com/CristiGhn/darkmode-webview。
Xcode 项目还包含一个 darkmode.html,它的工作原理与上面的照片完全一样。
谢谢!
使用这个 tutorial 我用 mix-blend-mode 实现了效果:差异。
在文档开始和文档结束的webiew中注入多个WKUserScript:
- JavaScript 文件在文档开始时具有切换功能
- 注入 div 具有背景和搅拌器的容器,这将使混合差异(在文档末尾)
文档末尾 CSS 文件的内部样式标签内容
let webConfiguration = WKWebViewConfiguration()
let contentController = WKUserContentController()
// Libray script an document start
let darkModeScript = WKUserScript(source: self.darkModeLibraryJS, injectionTime: WKUserScriptInjectionTime.atDocumentStart, forMainFrameOnly: false)
contentController.addUserScript(darkModeScript)
let injectDarkModeScript = WKUserScript(source: self.injectDarkModeJS, injectionTime: WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: false)
contentController.addUserScript(injectDarkModeScript)
let injectCSScript = WKUserScript(source: self.injectCSS, injectionTime: WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: false)
contentController.addUserScript(injectCSScript)
webConfiguration.userContentController = contentController
self.webview = WKWebView(frame: CGRect.zero, configuration: webConfiguration)
self.webview?.navigationDelegate = self
self.view.addSubview(webview!)
self.webview!.loadHTMLString(html, baseURL: nil)
JavaScript 具有切换功能并注入 CSS (darkmode.js)
function injectCSS(css) {
head = document.head || document.getElementsByTagName('head')[0],
style = document.createElement('style');
head.appendChild(style);
style.type = 'text/css';
if (style.styleSheet){
// This is required for IE8 and below.
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
}
function showDarkMode() {
var blender = document.getElementById('blender')
if (blender.hasAttribute("hidden")) {
blender.removeAttribute("hidden")
}
}
function showOriginalMode() {
var blender = document.getElementById('blender')
if (!blender.hasAttribute("hidden")) {
blender.setAttribute("hidden", true)
}
}
JavaScript 将 div 容器添加到 Web 视图的 DOM (inject-darkmode.js)
var container = document.createElement('div')
container.id = 'darkmode-container'
document.body.appendChild(container)
var background = document.createElement('div')
background.classList.add('darkmode-background')
container.appendChild(background)
var blender = document.createElement('div')
blender.id = 'blender'
blender.setAttribute('hidden', true)
container.appendChild(blender)
CSS 用于定义搅拌机和背景 (darkmode.css)
#blender {
width: 100vw;
height: 100vh;
left: 0pt;
top: 0pt;
position: fixed;
background: white;
transition: all 1s ease;
mix-blend-mode: difference;
}
img {
isolation: isolate;
}
.darkmode-background {
position: fixed;
background: white;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: -1;
}
我已经使用这个很棒的 tutorial.
的源代码在网站 html 页面上成功获得了随机 HTML 的暗模式效果我上传这些照片是为了更好地解释我得到的东西。
我正在尝试在 WKWebView 上获得相同的内容。 HTML 是从 API 加载的,所以我使用 WKWebView.loadHTMLString 方法。 对于此示例,演示 HTML 保存在 Xcode 项目的文件中。 此外,我还在 Xcode 中添加了 2 个 javascript 文件:darkmode.min.js(这是库)和 darkmode-options.js(底部切换的位置和文本标签页面)。 我认为我没有使用 WKUserScript 正确注入 2 个脚本。显然 darkmode.min.js 必须在 darkmode-options.js 之前加载。这就是为什么我使用 WKUserScriptInjectionTime.atDocumentStart 和 WKUserScriptInjectionTime.atDocumentEnd.
此外,当我在控制台中打印 HTML 的查看源代码时,它不显示已插入的脚本。
private func initWebView() {
let html = self.demoHTML
let jsLibrary = self.darkModeLibraryJS
let jsOptions = self.darkModeOptionsJS
let webConfiguration = WKWebViewConfiguration()
let contentController = WKUserContentController()
// Libray script an document start
let userScript = WKUserScript(source: jsLibrary, injectionTime: WKUserScriptInjectionTime.atDocumentStart, forMainFrameOnly: false)
contentController.addUserScript(userScript)
// Options script and document end
let optionsScript = WKUserScript(source: jsOptions, injectionTime: WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: false)
contentController.addUserScript(optionsScript)
webConfiguration.userContentController = contentController
self.webview = WKWebView(frame: CGRect.zero, configuration: webConfiguration)
self.webview?.navigationDelegate = self
self.view.addSubview(webview!)
self.webview!.loadHTMLString(html, baseURL: nil)
self.webview!.fillSuperview() // after view has been added as subview
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.chechHTML()
}
private func chechHTML() {
let script = "document.documentElement.outerHTML.toString()"
self.webview?.evaluateJavaScript(script, completionHandler: { (html, error) in
if html != nil {
print("❌: check html response", html ?? "")
}
if error != nil {
print("❌: check html with error", error ?? "")
}
})
}
项目上传于 github:https://github.com/CristiGhn/darkmode-webview。 Xcode 项目还包含一个 darkmode.html,它的工作原理与上面的照片完全一样。
谢谢!
使用这个 tutorial 我用 mix-blend-mode 实现了效果:差异。
在文档开始和文档结束的webiew中注入多个WKUserScript:
- JavaScript 文件在文档开始时具有切换功能
- 注入 div 具有背景和搅拌器的容器,这将使混合差异(在文档末尾)
文档末尾 CSS 文件的内部样式标签内容
let webConfiguration = WKWebViewConfiguration() let contentController = WKUserContentController() // Libray script an document start let darkModeScript = WKUserScript(source: self.darkModeLibraryJS, injectionTime: WKUserScriptInjectionTime.atDocumentStart, forMainFrameOnly: false) contentController.addUserScript(darkModeScript) let injectDarkModeScript = WKUserScript(source: self.injectDarkModeJS, injectionTime: WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: false) contentController.addUserScript(injectDarkModeScript) let injectCSScript = WKUserScript(source: self.injectCSS, injectionTime: WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: false) contentController.addUserScript(injectCSScript) webConfiguration.userContentController = contentController self.webview = WKWebView(frame: CGRect.zero, configuration: webConfiguration) self.webview?.navigationDelegate = self self.view.addSubview(webview!) self.webview!.loadHTMLString(html, baseURL: nil)
JavaScript 具有切换功能并注入 CSS (darkmode.js)
function injectCSS(css) {
head = document.head || document.getElementsByTagName('head')[0],
style = document.createElement('style');
head.appendChild(style);
style.type = 'text/css';
if (style.styleSheet){
// This is required for IE8 and below.
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
}
function showDarkMode() {
var blender = document.getElementById('blender')
if (blender.hasAttribute("hidden")) {
blender.removeAttribute("hidden")
}
}
function showOriginalMode() {
var blender = document.getElementById('blender')
if (!blender.hasAttribute("hidden")) {
blender.setAttribute("hidden", true)
}
}
JavaScript 将 div 容器添加到 Web 视图的 DOM (inject-darkmode.js)
var container = document.createElement('div')
container.id = 'darkmode-container'
document.body.appendChild(container)
var background = document.createElement('div')
background.classList.add('darkmode-background')
container.appendChild(background)
var blender = document.createElement('div')
blender.id = 'blender'
blender.setAttribute('hidden', true)
container.appendChild(blender)
CSS 用于定义搅拌机和背景 (darkmode.css)
#blender {
width: 100vw;
height: 100vh;
left: 0pt;
top: 0pt;
position: fixed;
background: white;
transition: all 1s ease;
mix-blend-mode: difference;
}
img {
isolation: isolate;
}
.darkmode-background {
position: fixed;
background: white;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: -1;
}