从资源中将 javascript 加载到 UIWebView 中

发布于 2024-11-02 16:32:33 字数 2354 浏览 0 评论 0 原文

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

如果 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 到文档文件夹中的资源而不是应用程序包

编辑:

我无需进行字符串替换和 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 [email protected]:pyramation/math-test.git

I need to load javascript files from my apps resources folder. As of right now, it does read images from the resources just fine, but it's not reading javascripts for some reason.

I have been able to render html docs that reference these javascripts if the html files themselves are written into the resources, but I would like to render html/js by setting the html of a UIWebView so it can be dynamic.

Here is what I am doing:

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]];

Now, if I change the base url to my server which also has the required files, it does load correctly. It would be great to not require an internet connection. Any help is appreciated!!! ;)

I found this useful in getting images to display: iPhone Dev: UIWebView baseUrl to resources in Documents folder not App bundle

Edit:

Instead of doing the string replacing and URL encoding, I was able to get images to by simply calling resourceURL on the mainBundle, but still no javascript execution.

    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]];

EDIT

If you want to help give this a shot, I have made it easier for you by creating an example project!

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

git clone [email protected]:pyramation/math-test.git

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

少女的英雄梦 2024-11-09 16:32:33

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

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

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

在此处输入图像描述

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 上无法正常工作,您可能需要使用 关闭该标记

Here we go with a simple setup.

Create the following folder structure in your Resources folder.

Note that the blue folders are referenced ones

enter image description here

The css is just candy :) In lib.js resides your javascript code which you'd like to use.

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');
}

Loading of the content in the webview

Note: webView is a property, view created with instance builder

- (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]]]];
}

And this should be the results:

enter image description here
enter image description here

EDIT:

snowman4415 mentioned that iOS 7 does not like self closing tags script tags, so if something is not working on iOS 7, you may need to close the tag with </script>

二智少女 2024-11-09 16:32:33

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

Here is another way to inject a local javascript file into the DOM of a web view. You load the contents of the JS file into a string and then use 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];
    // ...
}

This is especially useful when you don't own the *.html/xhtml files you are displaying (i.e. ePub reader. or news aggregator). It helps so that you don't have to worry about the relative paths from your xhtml file to your js file.

凉城 2024-11-09 16:32:33

这就是我使用 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")

    }
}

This is how I did using Webview and local JS. Putting some snapshots here a sample project here

Resources

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

    }
}
清风挽心 2024-11-09 16:32:33

在 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方法

In swift 3.x we can use loadHTMLString(_ string: String, baseURL: URL?)
function which is used for displaying script in 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)
     }
    }

Note:- We can set height of UIWebView as i mentioned above in
webViewDidFinishLoad method

睫毛上残留的泪 2024-11-09 16:32:33

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

Swift

从字符串加载脚本

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 类并使用其评估 JavaScript:completionHandler: 方法。但 WKWebView 从 iOS 8.0 及更高版本可用。

strong textWe can run custom JavaScript on a UIWebView using the method stringByEvaluatingJavaScriptFromString().This method returns the result of running the JavaScript script passed in the script parameter, or nil if the script fails.

Swift

Load script from String

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

Load script from Local file

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

Load script from String

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

Load script from Local file


//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];

enter image description here

Note The stringByEvaluatingJavaScriptFromString: method waits synchronously for JavaScript evaluation to complete. If you load web content whose JavaScript code you have not vetted, invoking this method could hang your app. Best practice is to adopt the WKWebView class and use its evaluateJavaScript:completionHandler: method instead. But WKWebView is available from iOS 8.0 and later.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文