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

如何在WKWebView中注入多份用户脚本以实现暗黑模式效果?

Fixing Dark Mode Injection in WKWebView

Let's break down your problem and fix it step by step:

First, a Key Clarification

You mentioned you don't see the injected scripts in the HTML source printed by chechHTML() — this is normal behavior. WKUserScript injects scripts directly into the WebKit JavaScript runtime, not by modifying the original HTML document structure. So using document.documentElement.outerHTML will never show these injected scripts, even if they're working correctly. That's not the root of your issue.

Step 1: Verify Your Local JS Files Are Loaded Correctly

First, make sure you're actually reading the full content of darkmode.min.js and darkmode-options.js into your jsLibrary and jsOptions variables. Add debug prints right before creating the user scripts to confirm:

print("Loaded darkmode library content:\n", jsLibrary)
print("Loaded darkmode options content:\n", jsOptions)
  • If the output is empty or truncated, check that the JS files are added to your Xcode project and their Target Membership is enabled for your app target.
  • Ensure your file reading code (where you populate darkModeLibraryJS and darkModeOptionsJS) doesn't have errors (e.g., incorrect file paths).

Step 2: Adjust Script Execution Timing & Logic

Your injection timing (atDocumentStart for the library, atDocumentEnd for options) is correct, but you need to ensure the options script runs only after the DOM is ready (and the Darkmode class is fully available).

If your darkmode-options.js has code like this (immediate execution):

const darkmodeOptions = {
  bottom: "32px",
  right: "32px",
  label: "🌓"
};
const darkmode = new Darkmode(darkmodeOptions);
darkmode.showWidget();

Wrap it in a DOMContentLoaded listener to guarantee it runs after the DOM is built:

document.addEventListener("DOMContentLoaded", function() {
  const darkmodeOptions = {
    bottom: "32px",
    right: "32px",
    label: "🌓"
  };
  const darkmode = new Darkmode(darkmodeOptions);
  darkmode.showWidget();
});

This matches how your working darkmode.html likely loads the scripts (waiting for the page to be ready before initializing the widget).

Step 3: Verify Scripts Are Actually Injecting & Working

Instead of checking the HTML source, validate the JavaScript environment directly. Update your didFinish navigation method to test if Darkmode is available:

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    // Check if Darkmode library exists
    webView.evaluateJavaScript("typeof Darkmode !== 'undefined'") { (result, error) in
        if let exists = result as? Bool, exists {
            print("✅ Darkmode library loaded successfully!")
            // Try initializing the widget
            webView.evaluateJavaScript("new Darkmode({bottom: '32px', right: '32px'}).showWidget()") { (_, initError) in
                if let initError = initError {
                    print("❌ Failed to initialize Darkmode widget:", initError.localizedDescription)
                } else {
                    print("✅ Darkmode widget is active!")
                }
            }
        } else {
            print("❌ Darkmode library is NOT loaded. Check your script injection.")
        }
    }
    // self.chechHTML() // This won't show injected scripts, so you can remove it
}

Step 4: Fix the loadHTMLString Base URL

When using loadHTMLString(_:baseURL:) with baseURL: nil, WebKit treats the document as "originless", which can break features like localStorage (if the Darkmode library relies on it). Set a valid base URL using your app's bundle:

let baseURL = Bundle.main.bundleURL
self.webview!.loadHTMLString(html, baseURL: baseURL)

Step 5: Cross-Reference Your Working darkmode.html

Compare the script content in your working HTML file to the content you're injecting. Ensure:

  • The injected darkmode.min.js is identical to the one referenced in darkmode.html
  • The options logic in darkmode-options.js matches the initialization code in the working HTML (no typos or missing configs)

内容的提问来源于stack exchange,提问作者Cristi Ghinea

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:18:19