Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IOS UIWebView: How to add listeners to DOM events?

How can I add listeners to DOM events in UIWebView? For example for the following html:

<button type="button" id="button1">Try it</button>

Is it possible to register a listener for a button click event in IOS application that loads html in UIWebView?

like image 409
Anton Ashanin Avatar asked Dec 02 '13 12:12

Anton Ashanin


2 Answers

Yes, you can do this with crafted url and UIWebViewDelegate methods.

First, to add event listener on button tag, you should execute javascript like below (after the page is loaded)

// In the UIWebViewDelegate
- (void)webViewDidFinishLoad:(UIWebView *)webView {
    if (/* when the loaded url is the target */) {
        NSString *js = @"document.getElementById('button').click = function() { window.location = 'my-protocol://dummmy.com/maybe/some/data';}";
        [webView stringByEvaluatingJavaScriptFromString: js];
    }
}

We bind a click event on the button, and when it's clicked, it will trigger a request to webView.

And the next thing we gotta do is to intercept the request and do what you want in ObjC.

// In the UIWebViewDelegate
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    if (/* when the url of the request is the crafted url */) {
        // call your objc method...
    }
}
like image 163
Egist Li Avatar answered Oct 11 '22 21:10

Egist Li


Here is the Swift way to intercept when a Link is clicked in the UIWebView:

Get yourself a delegate:

class ViewController: UIViewController, UIWebViewDelegate { //... }

And assign it:

override func viewDidLoad() {
        super.viewDidLoad()

        webView.delegate = self

        //...
}

Now we can use it to intercept:

    func webViewDidFinishLoad(_ webView: UIWebView) {
            if (currentURL?.lowercased().range(of:"some/url") != nil) {
                webView.stringByEvaluatingJavaScript(from: "document.getElementsByTagName('a')[0].onclick = function() {window.location = 'injected://loadPDF1'; return false;}")
            }
    }

    // Sent before a web view begins loading a frame.
    func webView(_: UIWebView, shouldStartLoadWith: URLRequest, navigationType: UIWebViewNavigationType) -> Bool{
        // intercept all injected page calls
        if (shouldStartLoadWith.url?.scheme == "injected") {
            return false;
        }
        return true;
    }
like image 37
Hans Avatar answered Oct 11 '22 21:10

Hans