【问题标题】:Loading javascript into a UIWebView from resources从资源中将 javascript 加载到 UIWebView
【发布时间】:2011-08-09 16:26:51
【问题描述】:

我需要从我的应用资源文件夹中加载 javascript 文件。截至目前,它确实可以很好地从资源中读取图像,但由于某种原因它没有读取 javascripts。

如果 html 文件本身被写入资源,我已经能够呈现引用这些 javascripts 的 html 文档,但我想通过设置 UIWebView 的 html 来呈现 html/js,以便它可以是动态的。

这是我正在做的事情:

NSString * html = @"<!DOCTYPE html><html><head><title>MathJax</title></head><body><script type=\"text/x-mathjax-config\">MathJax.Hub.Config({tex2jax: {inlineMath: [[\"$\",\"$\"],[\"\\(\",\"\\)\"]]}});</script><script type=\"text/javascript\" src=\"/MathJax/MathJax.js\"></script>$$\\int_x^y f(x) dx$$<img src=\"coffee.png\"></body></html>";

NSString * path = [[NSBundle mainBundle] resourcePath]; 
path = [path stringByReplacingOccurrencesOfString:@"/" withString:@"//"];
path = [path stringByReplacingOccurrencesOfString:@" " withString:@"%20"];

NSString * resourcesPath = [[NSString alloc] initWithFormat:@"file://%@/", path];
[webview loadHTMLString:html baseURL:[NSURL URLWithString:resourcesPath]];

现在,如果我将基本 url 更改为我的服务器也有所需的文件,它确实可以正确加载。不需要互联网连接会很棒。任何帮助表示赞赏! ;)

我发现这对显示图像很有用:iPhone Dev: UIWebView baseUrl to resources in Documents folder not App bundle

编辑:

我可以通过简单地调用 mainBundle 上的 resourceURL 来获取图像,而不是进行字符串替换和 URL 编码,但仍然没有执行 javascript。

    NSString * setHtml = @"<!DOCTYPE html><html><head><title>MathJax</title></head><body><script type=\"text/x-mathjax-config\">MathJax.Hub.Config({tex2jax: {inlineMath: [[\"$\",\"$\"],[\"\\(\",\"\\)\"]]}});</script><script type=\"text/javascript\" src=\"/MathJax/MathJax.js\"></script>$$\\int_x^y f(x) dx$$<img src=\"images/test.png\"></body></html>";
    [webview loadHTMLString:setHtml baseURL:[[NSBundle mainBundle] resourceURL]];

编辑

如果您想帮助尝试一下,我通过创建示例项目让您更轻松!

https://github.com/pyramation/math-test

git clone git@github.com:pyramation/math-test.git

【问题讨论】:

标签: javascript xcode ios resources mathjax


【解决方案1】:

strong text我们可以使用 stringByEvaluatingJavaScriptFromString() 方法在 UIWebView 上运行自定义 JavaScript。此方法返回脚本参数中传递的 JavaScript 脚本的运行结果,如果脚本失败,则返回 nil。

斯威夫特

从字符串加载脚本

webview.stringByEvaluatingJavaScriptFromString(“alert(‘This is JavaScript!’);”) 

从本地文件加载脚本

//Suppose you have javascript file named "JavaScript.js" in project.
let filePath = NSBundle.mainBundle().pathForResource("JavaScript", ofType: "js")
        do {
let jsContent = try String.init(contentsOfFile: filePath!, encoding:
NSUTF8StringEncoding)
webview.stringByEvaluatingJavaScriptFromString(jsContent)
        }
catch let error as NSError{
            print(error.debugDescription)
}

Objective-C

从字符串加载脚本

[webview stringByEvaluatingJavaScriptFromString:@”alert(‘This is JavaScript!’);”];

从本地文件加载脚本


//Suppose you have javascript file named "JavaScript.js" in project.
NSString *filePath = [[NSBundle mainBundle] pathForResource:@”JavaScript” ofType:@”js”];
NSString *jsContent = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
[webview stringByEvaluatingJavaScriptFromString:jsContent];

注意 stringByEvaluatingJavaScriptFromString: 方法同步等待 JavaScript 评估完成。如果您加载的 Web 内容的 JavaScript 代码未经审查,则调用此方法可能会挂起您的应用程序。最佳实践是采用 WKWebView 类并改用其 evaluateJavaScript:completionHandler: 方法。但 WKWebView 在 iOS 8.0 及更高版本中可用。

【讨论】:

    【解决方案2】:

    在 swift 3.x 中我们可以使用loadHTMLString(_ string: String, baseURL: URL?) 用于在UIWebview中显示脚本的函数

     @IBOutlet weak var webView : UIWebView!
        class ViewController: UIViewController,UIWebViewDelegate {
    
           override func viewDidLoad() {
                super.viewDidLoad()
                webView.delegate = self
         }
         func loadWebView() {
                webView.loadHTMLString("<p>Hello, How are you doing?.</p>" , baseURL: nil)
            }
         func webViewDidFinishLoad(_ webView: UIWebView) {
                webView.frame.size.height = 1
                webView.frame.size = webView.sizeThatFits(.zero)
         }
        }
    

    注意:- 我们可以设置 UIWebView 的高度,正如我上面提到的 webViewDidFinishLoad 方法

    【讨论】:

      【解决方案3】:

      这就是我使用 Webview 和本地 JS 的方式。在此处放一些快照作为示例项目here

      // Get the path for index.html, where in which index.html has reference to the js files, since we are loading from the proper resource path, the JS files also gets picked up properly from the resource path.
      
      func loadWebView(){
      
          if let resourceUrl = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "WebDocs2"){
              let urlRequest = URLRequest.init(url: resourceUrl)
              myWebView.loadRequest(urlRequest)
          }
      }
      

      // Load the JS from resources
      func jsScriptText() -> String? {
      
          guard let jsPath = Bundle.main.path(forResource: "hello", ofType: "js", inDirectory: "WebDocs2/scripts") else {
      
              return nil
          }
          do
          {
              let jsScript = try String(contentsOfFile: jsPath, encoding: String.Encoding.utf8)
              return jsScript
          }catch{
      
              print("Error")
              return nil
          }
      
      }
      // Run the java script
      func runJS(){
      
          if let jsScript = jsScriptText(){
      
              let jsContext = JSContext()
              _ = jsContext?.evaluateScript(jsScript)
              let helloJSCore = jsContext?.objectForKeyedSubscript("helloJSCore")
              let result = helloJSCore?.call(withArguments: [])
              print(result?.toString() ?? "Error")
      
          }
      }
      

      【讨论】:

        【解决方案4】:

        我们在这里进行简单的设置。

        在您的资源文件夹中创建以下文件夹结构。

        请注意,蓝色文件夹是引用的文件夹

        css 只是糖果 :) 在 lib.js 中驻留您想要使用的 javascript 代码。

        index.html

        <html>
            <head>
                <link rel="stylesheet" type="text/css" href="css/standard.css">
        
                <script src="js/lib.js" type="text/javascript" />
            </head>
            <body>
                <h2>Local Javascript</h2>
        
                <a href="javascript:alert('Works!')">Test Javascript Alert</a>      
        
                <br/>
                <br/>
        
                <a href="javascript:alertMeWithMyCustomFunction('I am');">External js test</a>
            </body>
        </html>
        

        lib.js

        function alertMeWithMyCustomFunction(text) {
            alert(text+' -> in lib.js');
        }
        

        在 webview 中加载内容

        注意:webView 是一个属性,使用实例构建器创建的视图

        - (void)viewDidLoad
        {   
            NSString *htmlPath = [[NSBundle mainBundle] pathForResource:@"index" 
                                                                 ofType:@"html" 
                                                            inDirectory:@"/htdocs" ];
        
            NSString *html = [NSString stringWithContentsOfFile:htmlPath 
                                                       encoding:NSUTF8StringEncoding 
                                                          error:nil];
        
            [webView loadHTMLString:html 
                            baseURL:[NSURL fileURLWithPath:
                                     [NSString stringWithFormat:@"%@/htdocs/", 
                                     [[NSBundle mainBundle] bundlePath]]]];
        }
        

        这应该是结果:

        编辑:

        snowman4415 提到 iOS 7 不喜欢自闭合标签脚本标签,因此如果在 iOS 7 上出现问题,您可能需要使用 &lt;/script&gt; 关闭标签

        【讨论】:

        • 你有没有试过我做的例子?这种方法似乎不起作用。我添加了 [webview loadHTMLString:setHtml baseURL:[NSURL fileURLWithPath: [[NSBundle mainBundle] bundlePath]]];没有运气。
        • @Nick 在 github 链接上查看 DynamicHTMLWebViewController.m,我将您的建议放在那里。你能看一下吗?
        • @pyramation 你能用解压版的 MathJax 创建项目吗?它确实进入了js,但里面出了点问题。
        • @Nick,我将解压后的版本添加到了 git 存储库中,但是我不确定它是否有帮助,因为当我切换到本地时,它甚至无法正常工作。所以我把包装和拆包都放在那里
        • @pyramation,我真的很想帮忙,但只要解压版本不起作用,我认为没有机会调试这个:我试图让解压版本与本地测试一起工作,但这没有做任何事情。其实我对 MathJax 并不熟悉。
        【解决方案5】:

        这是将本地 javascript 文件注入 Web 视图的 DOM 的另一种方法。你把JS文件的内容加载成字符串,然后使用stringByEvalutatingJavaScriptFromString

        - (void)webViewDidFinishLoad:(UIWebView *)webView {
            NSString *jsFile = @"jquery-1.8.2.min.js";
            NSString *jsFilePath = [[NSBundle mainBundle] pathForResource:jsFile ofType:nil];
            NSURL *jsURL = [NSURL fileURLWithPath:jsFilePath];
            NSString *javascriptCode = [NSString stringWithContentsOfFile:jsURL.path encoding:NSUTF8StringEncoding error:nil];
            [webView stringByEvaluatingJavaScriptFromString:javascriptCode];
            // ...
        }
        

        当您不拥有正在显示的 *.html/xhtml 文件(即 ePub 阅读器或新闻聚合器)时,这尤其有用。它有助于您不必担心从 xhtml 文件到 js 文件的相对路径。

        【讨论】:

        • 不错!终于明白了
        • 在最新的 Swift 版本中与此等价的是什么?
        • CSS 文件呢?
        • Apple 开发指南建议使用 evaluateJavaScript:completionHandler: 代替 - 您还可以获得一个完成处理程序!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-12-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多