Loading javascript into a UIWebView from resources

别来无恙 提交于 2019-11-26 05:56:16

问题


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 git@github.com:pyramation/math-test.git

回答1:


Here we go with a simple setup.

Create the following folder structure in your Resources folder.

Note that the blue folders are referenced ones

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:

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>




回答2:


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.




回答3:


This is how I did using Webview and local JS. Putting some snapshots here a sample project 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:


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




回答5:


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

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.



来源:https://stackoverflow.com/questions/5733883/loading-javascript-into-a-uiwebview-from-resources

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!