【问题标题】:Embedded Webkit - script callbacks how?Embedded Webkit - 脚本回调如何?
【发布时间】:2011-01-18 07:36:16
【问题描述】:

在 Windows 上,当“Shell.Explorer”ActiveX 控件嵌入到应用程序中时,可以在实现 IDispatch 的对象上注册“外部”处理程序,以便网页上的脚本可以调用宿主应用。

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

现在,我转向 Mac 开发,并认为我可以通过嵌入在我的 Cocoa 应用程序中的 WebKit 获得类似的工作。但是,似乎确实没有任何工具可以让脚本回调到托管应用程序。

一条建议是挂钩window.alert 并让脚本将格式化的消息字符串作为警报字符串传递。 我还想知道是否可以使用 NPPVpluginScriptableNPObject 将 WebKit 定向到应用程序托管的 NPAPI 插件。

我错过了什么吗?承载一个 WebView 并允许脚本与宿主交互真的有这么难吗?

【问题讨论】:

    标签: cocoa webkit npapi


    【解决方案1】:

    您需要实现各种 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: 方法。

    【讨论】:

    • [webView mainFrame] loadData: 是否触发 didClearWindowObject: ?我有 [webView setFrameLoadDelegate:self];设置,但是当我尝试断点时,这不是设置 windowScriptObject。
    • 我是这样运行的,但是你如何从 Cocoa 调用处理程序(JS 函数),作为 Cocoa 中发生的事情的回调。当然,您可以从WebView 获取windowScriptObject,但有没有办法让Cocoa 知道它属于哪个WebScriptObject 实例?
    • 伟大的。谢谢! ;-)
    • 注意!!!! [windowScriptObject setValue:self forKey:@"Cocoa"];保留一个强引用,给定的代码(通过 self)将创建一个保留循环(只是解决这个问题)
    【解决方案2】:

    WebScriptObject API 与 JavaScriptCore 框架结合使用非常容易。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-20
      • 1970-01-01
      相关资源
      最近更新 更多