将 javascript 从资源加载到 UIWebView

IT技术 javascript xcode ios resources mathjax
2021-01-31 07:49:06

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

如果将 html 文件本身写入资源中,我已经能够呈现引用这些 javascript 的 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

编辑:

我没有进行字符串替换和 URL 编码,而是通过简单地调用 mainBundle 上的 resourceURL 来获取图像,但仍然没有执行 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
5个回答

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

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

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

在此处输入图片说明

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

索引.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>

库.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 上不起作用,你可能需要关闭标签 </script>

@Nick 在 github 链接上查看 DynamicHTMLWebViewController.m,我把你的建议放在那里。你能看看吗?
2021-03-29 07:49:06
@Nick,我将解压版本添加到 git 存储库中,但是我不确定它是否有帮助,因为当我切换到它时本地甚至都不起作用。所以我把打包和拆包都放在那里
2021-03-30 07:49:06
你有没有尝试过我做的例子?这个方法好像不行。我添加了 [webview loadHTMLString:setHtml baseURL:[NSURL fileURLWithPath: [[NSBundle mainBundle] bundlePath]]]; 没有运气。
2021-04-01 07:49:06
@pyramation 你能用 MathJax 的解压版本创建项目吗?它确实进入了 js,但内部出了点问题。
2021-04-03 07:49:06
@pyramation,我真的很想提供帮助,但只要解压版本不起作用,我认为没有机会对此进行调试:我试图让解压版本与本地测试一起使用,但没有什么都不做 其实我对 MathJax 并不熟悉。
2021-04-10 07:49:06

这是将本地 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 文件的相对路径。

Apple 开发指南建议使用evaluateJavaScript:completionHandler: 来代替——您还可以获得一个完成处理程序!
2021-03-16 07:49:06
在最新的 Swift 版本中,与此等效的是什么?
2021-03-24 07:49:06
CSS文件呢?
2021-03-28 07:49:06
好的 !!终于明白了
2021-04-12 07:49:06

这就是我使用 Webview 和本地 JS 的方式。把一些快照放在这里 一个示例项目在这里

资源

// 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")

    }
}

在 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)
     }
    }

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

强文本我们可以使用 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)
}

目标-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 及更高版本中可用。