【问题标题】:Insert CSS into loaded HTML in UIWebView / WKWebView将 CSS 插入 UIWebView / WKWebView 中加载的 HTML
【发布时间】:2016-01-12 09:49:42
【问题描述】:

我能够成功获取 HTML 内容并显示到我的 UIWebView 中。

但想通过添加外部 CSS 文件来自定义内容。我只能更改文本和字体的大小。我尝试了所有可能的解决方案来进行更改,但它不起作用 - 它没有显示任何更改。

下面是我的代码

HTMLNode* body = [parser body];
HTMLNode* mainContentNode = [body  findChildWithAttribute:@"id" matchingName:@"main_content" allowPartial:NO];
NSString *pageContent = [NSString stringWithFormat:@"%@%@", cssString, contentHtml];
        [webView loadHTMLString:pageContent baseURL:[NSURL URLWithString:@"http://www.example.org"]];

-(void)webViewDidFinishLoad:(UIWebView *)webView1{
    int fontSize = 50;
    NSString *font = [[NSString alloc] initWithFormat:@"document.getElementsByTagName('body')[0].style.webkitTextSizeAdjust= '%d%%'", fontSize];
    NSString *fontString = [[NSString alloc] initWithFormat:@"document.getElementById('body').style.fontFamily=\"helvetica\""];

    [webView1 stringByEvaluatingJavaScriptFromString:fontString];
    [webView1 stringByEvaluatingJavaScriptFromString:font];
}

请帮我在我的视图中获取 css 样式表。

【问题讨论】:

    标签: ios objective-c uiwebview wkwebview


    【解决方案1】:

    我尝试了 Amer Hukic 的答案。但并没有像现在这样工作。我在我的 html 头标签之间添加了以下代码。

    <link rel="stylesheet" href="style.css">
    

    【讨论】:

      【解决方案2】:

      你需要在苹果样式到HTML之前添加这个header

      let fontName = UIFont.systemFont(ofSize: 17.0).fontName
          let htmlContent = """
          <header>
          <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no'>
          </header>
          <style type='text/css'>
          img{max-height: 100%; min-height: 100%; height:auto; max-width: 100%; width:auto;margin-bottom:5px;}
          p{text-align:left|right|center; line-height: 180%; font-family: '\(fontName)'; font-size: 17px;}
          iframe{width:100%; height:250px;}
          </style> \(html)
          """
          webView.loadHTMLString(htmlContent, baseURL: Bundle.main.bundleURL)
      

      【讨论】:

        【解决方案3】:

        与其将css与样式标签一起应用,不如将其与链接标签一起应用:

        func insertContentsOfCSSFile2(into webView: WKWebView) {
            guard let path = Bundle.main.path(forResource: "resource", ofType: "css") else { return }                
            let csFile = "var head = document.getElementsByTagName('head')[0];var link = document.createElement('link'); link.rel = 'stylesheet';link.type = 'text/css';link.href = '\(path)';link.media = 'all';head.appendChild(link);"
        
            webView.evaluateJavaScript(csFile) {(result, error) in
                if let error = error {
                    print(error)
                }
            }
        }
        

        我已经测试过了。 它工作正常。

        【讨论】:

          【解决方案4】:

          由于 UIWebView 在 iOS 12 中已弃用,我将只回答 WKWebView。 我已经实现了 CSS 加载,就像在接受的答案中描述的那样。问题是有时从没有应用 CSS 的 HTML 到有 CSS 的 HTML 的过渡是可见的。
          我认为更好的方法是使用WKUserScript 像这样注入CSS:

          lazy var webView: WKWebView = {
              guard let path = Bundle.main.path(forResource: "style", ofType: "css") else {
                  return WKWebView()
              }
          
              let cssString = try! String(contentsOfFile: path).components(separatedBy: .newlines).joined()
              let source = """
                var style = document.createElement('style');
                style.innerHTML = '\(cssString)';
                document.head.appendChild(style);
              """
          
              let userScript = WKUserScript(source: source,
                                            injectionTime: .atDocumentEnd,
                                            forMainFrameOnly: true)
          
              let userContentController = WKUserContentController()
              userContentController.addUserScript(userScript)
          
              let configuration = WKWebViewConfiguration()
              configuration.userContentController = userContentController
          
              let webView = WKWebView(frame: .zero,
                                      configuration: configuration)
              return webView
          }()
          

          您可以在blog post 中阅读有关此方法的更多信息。

          【讨论】:

          • 我遇到了同样的问题。过渡是可见的。它就像魅力一样。谢谢!!
          • 这很完美。注入css时结果html不闪烁。
          • 这是一种在 iOS 12 上实现的方法,我为此苦苦挣扎了很长时间。非常感谢!
          • 太棒了!很高兴我找到了这条评论。此解决方案没有故障。
          • 另一种解决方案对我不起作用,但确实如此。
          【解决方案5】:

          有关更完整的详细信息,请参阅@joern 接受的答案。我添加这个答案是因为我遇到了一个奇怪的边缘情况。我的特定用例需要使用class="dialog"div 添加样式。出于某种原因,使用.dialogdiv 的样式不起作用,尽管其他类型的样式正在工作。最后我使用以下设置dialog的宽度

          let width = Int(webView.bounds.width)
          let script = "document.getElementsByClassName(\"dialog\")[0].style.width = \"\(width)px\""
          webView.evaluateJavaScript(script)
          

          【讨论】:

            【解决方案6】:

            你可以这样做:

            - (void)webViewDidFinishLoad:(UIWebView *)webView {
                NSString *cssString = @"body { font-family: Helvetica; font-size: 50px }"; // 1
                NSString *javascriptString = @"var style = document.createElement('style'); style.innerHTML = '%@'; document.head.appendChild(style)"; // 2
                NSString *javascriptWithCSSString = [NSString stringWithFormat:javascriptString, cssString]; // 3
                [webView stringByEvaluatingJavaScriptFromString:javascriptWithCSSString]; // 4
            }
            

            这段代码的作用:

            // 1 : 定义一个包含所有 CSS 声明的字符串

            // 2 : 定义一个 javascript 字符串,该字符串创建一个新的&lt;style&gt; HTML DOM 元素并将 CSS 声明插入其中。实际上插入是在下一步中完成的,现在只有%@ 占位符。我这样做是为了防止线路变得太长,但第 2 步和第 3 步可以一起完成。

            // 3 : 合并两个字符串

            // 4:在UIWebView中执行javascript

            为此,您的 HTML 必须有一个 &lt;head&gt;&lt;/head&gt; 元素。

            编辑:

            您还可以从本地 css 文件(在本例中名为“styles.css”)加载 css 字符串。只需将步骤 //1 替换为以下内容:

            NSString *path = [[NSBundle mainBundle] pathForResource:@"styles" ofType:@"css"];
            NSString *cssString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
            

            作为另一种选择,您可以将 &lt;link&gt; 元素注入到加载 CSS 文件的 &lt;head&gt;

            - (void)webViewDidFinishLoad:(UIWebView *)webView {
                NSString *path = [[NSBundle mainBundle] pathForResource:@"styles" ofType:@"css"];
                NSString *javascriptString = @"var link = document.createElement('link'); link.href = '%@'; link.rel = 'stylesheet'; document.head.appendChild(link)";
                NSString *javascriptWithPathString = [NSString stringWithFormat:javascriptString, path];
                [webView stringByEvaluatingJavaScriptFromString:javascriptWithPathString];
            }
            

            此解决方案最适合大型 CSS 文件。不幸的是,它不适用于远程 HTML 文件。仅当您想将 CSS 插入到已下载到应用的 HTML 中时,才能使用此功能。

            更新:WKWebView / Swift 3.x

            当您使用WKWebView 时,由于WKWebView 的安全设置,注入&lt;link&gt; 元素不起作用。

            您仍然可以将 css 作为字符串注入。在您的代码 //1 中创建 CSS 字符串或将其放入本地文件 //2。请注意,使用 WKWebView 您必须在 WKNavigationDelegatewebView(_:didFinish:) 方法中进行注入:

            func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
                insertCSSString(into: webView) // 1
                // OR
                insertContentsOfCSSFile(into: webView) // 2
            }
            
            func insertCSSString(into webView: WKWebView) {
                let cssString = "body { font-size: 50px; color: #f00 }"
                let jsString = "var style = document.createElement('style'); style.innerHTML = '\(cssString)'; document.head.appendChild(style);"
                webView.evaluateJavaScript(jsString, completionHandler: nil)
            }
            
            func insertContentsOfCSSFile(into webView: WKWebView) {
                guard let path = Bundle.main.path(forResource: "styles", ofType: "css") else { return }
                let cssString = try! String(contentsOfFile: path).trimmingCharacters(in: .whitespacesAndNewlines)
                let jsString = "var style = document.createElement('style'); style.innerHTML = '\(cssString)'; document.head.appendChild(style);"
                webView.evaluateJavaScript(jsString, completionHandler: nil)
            }
            

            【讨论】:

            • 抱歉我的回复晚了:(你能解释一下这行是什么意思吗? NSString *javascriptString = @"var style = document.createElement('style'); style.innerHTML = '%@'; document.head.appendChild(style)"; 它对我不起作用..!
            • @Mansuu.... 尝试将 CSS 文件的内容(作为字符串)放入您的 HTML 字符串中。不要忘记将 CSS 嵌入到 Style 元素中 &lt;style type="text/css"&gt;YOUR CSS&lt;/style&gt;
            • 我认为 webView:didFinish:navigation: 不是最好的注入时间。
            • 它有效。但我必须将 cssString 包装到 single 行中。 """ 的多行不起作用。
            • 插入 &lt;link&gt; 也适用于 WKWebView 如果您将 wkWebView 设置为使用:wkWebView.loadHTMLString(html, baseURL: Bundle.main.resourceURL)
            猜你喜欢
            • 2017-03-22
            • 2017-05-24
            • 1970-01-01
            • 2020-05-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多