2010-02-18 48 views
13

在windows上,當「Shell.Explorer」ActiveX控件嵌入到應用程序中時,可以在實現IDispatch的對象上註冊一個「外部」處理程序,以便網頁上的腳本可以調用到宿主應用程序。嵌入式Webkit - 腳本回調如何?

<button onclick="window.external.Test('called from script code')">test</button> 

現在,我已經感動到Mac開發,我想我可以擺脫嵌入在我的Cocoa應用程序WebKit的類似工作的東西。但是,似乎沒有任何工具可以讓腳本回調主機應用程序。

一條建議是掛鉤window.alert並獲取腳本以傳遞格式化的消息字符串作爲警報字符串。 我也想知道WebKit是否可以使用NPPVpluginScriptableNPObject指向應用程序託管的NPAPI插件。

我錯過了什麼嗎?主持WebView並允許腳本與主機交互真的很難嗎?

回答

30

您需要實現各種WebScripting協議方法。這是一個基本的例子:

@interface WebController : NSObject 
{ 
    IBOutlet WebView* webView; 
} 

@end 

@implementation WebController 

//this returns a nice name for the method in the JavaScript environment 
+(NSString*)webScriptNameForSelector:(SEL)sel 
{ 
    if(sel == @selector(logJavaScriptString:)) 
     return @"log"; 
    return nil; 
} 

//this allows JavaScript to call the -logJavaScriptString: method 
+ (BOOL)isSelectorExcludedFromWebScript:(SEL)sel 
{ 
    if(sel == @selector(logJavaScriptString:)) 
     return NO; 
    return YES; 
} 

//called when the nib objects are available, so do initial setup 
- (void)awakeFromNib 
{ 
    //set this class as the web view's frame load delegate 
    //we will then be notified when the scripting environment 
    //becomes available in the page 
    [webView setFrameLoadDelegate:self]; 

    //load a file called 'page.html' from the app bundle into the WebView 
    NSString* pagePath = [[NSBundle mainBundle] pathForResource:@"page" ofType:@"html"]; 
    NSURL* pageURL = [NSURL fileURLWithPath:pagePath]; 
    [[webView mainFrame] loadRequest:[NSURLRequest requestWithURL:pageURL]]; 
} 


//this is a simple log command 
- (void)logJavaScriptString:(NSString*) logText 
{ 
    NSLog(@"JavaScript: %@",logText); 
} 

//this is called as soon as the script environment is ready in the webview 
- (void)webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)windowScriptObject forFrame:(WebFrame *)frame 
{ 
    //add the controller to the script environment 
    //the "Cocoa" object will now be available to JavaScript 
    [windowScriptObject setValue:self forKey:@"Cocoa"]; 
} 

@end 

在控制器執行此代碼後,您現在可以從JavaScript環境調用Cocoa.log('foo');logJavaScriptString:方法將被調用。

+0

[webView mainFrame] loadData:fire didClearWindowObject:?我有[webView setFrameLoadDelegate:self];設置,但是當我嘗試一個斷點時,這不是設置windowScriptObject。 – Luke 2010-05-12 04:23:23

+1

我知道它是以這種方式運行的,但是如何從Cocoa調用一個處理程序(JS函數),作爲可可中發生的回調。當然你可以從'WebView'中獲得'windowScriptObject',但是'Cocoa'知道它屬於哪個'WebScriptObject'實例嗎? – 2013-07-16 10:07:50

+0

太棒了。謝謝! ;-) – 2014-06-08 15:06:57