nfm
nfm

Reputation: 20707

How can my Cocoa application be notified of onClick events in a WebView?

I'm loading a WebView in my OSX application and want to receive a notification in my app when the user clicks on an element in the WebView. (The WebView is loading a web page that is part of my web application.)

Is this possible?

I can think of a way to do it (poll a javascript value that gets set on the click event) but I'm hoping there's a more sensible way!

Upvotes: 4

Views: 3187

Answers (4)

Carl Carlson
Carl Carlson

Reputation: 540

Malhal's solution did not work for me in Mac OS. WebView in Mac OS is weird and wkWebView is incomplete.

Having set the first responder to the webView, this one did:

- (void)sendEvent:(NSEvent *)event
{

if ([event type] == NSLeftMouseDown || [event type] == NSRightMouseDown)
{

    if([[self.firstResponder className] isEqualToString:@"WebHTMLView"])
    {
        NSLog(@"MouseDown at: %f, %f",event.locationInWindow.x,event.locationInWindow.y);
        return;
    }
}
[super sendEvent:event];

}

Upvotes: 0

b123400
b123400

Reputation: 6118

Since the web page is your web application, then I assume you have control over the html.

Use WebScript.

Here's a little demo:

Objective-C:

- (void)windowDidLoad{
    [[webView windowScriptObject] setValue:self forKey:@"objcConnector"];
    ....
}
+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector{
    if (aSelector == @selector(elementClicked:)) return NO;
    return YES;
}
-(void)elementClicked:(id)object{
    //object is the id of the element
}

HTML:

<button id="example" onClick="window.objcConnector.elementClicked_(this.id)">Click me</button>

Upvotes: 5

malhal
malhal

Reputation: 30719

Subclass NSWindow and catch the mouse down events on the WebView which is actually a WebHTMLView:

@interface MyWindow : NSWindow
@end

@implementation MyWindow

- (void)sendEvent:(NSEvent *)event
{

    if ([event type] == NSLeftMouseDown || [event type] == NSRightMouseDown)
    {
        NSView *deepView = [[self contentView] hitTest:[event locationInWindow]];
        if([[deepView className] isEqualToString:@"WebHTMLView"]){
            return;
        }
    }
    [super sendEvent:event];

}

@end

Then by monitoring the mouse over element delegate method you can track which element was clicked.

Upvotes: 1

Michael Villar
Michael Villar

Reputation: 289

I think this delegate method should be useful. Open a link from the WebView would call this method, so you can figure out what to do with it.

- (void)webView:(WebView *)sender
        decidePolicyForNavigationAction:(NSDictionary *)actionInformation
        request:(NSURLRequest *)request frame:(WebFrame *)frame
        decisionListener:(id<WebPolicyDecisionListener>)listener

Or you can listen to the WebView frame change URL :

- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame 

Upvotes: 1

Related Questions