Cocoa WebView Problems(window.open , innerhtml , scroll position)

很多时候,我们都在忙于解决问题,而不善于对解决问题中所使用的知识进行总结梳理,以至于过几天就想不起来,那几天自己干了什么,学到了什么。

这个周末主要研究解决了WebView相关的几个问题:

1.如何捕获WebView中javascript的window.open事件,并通过系统默认的浏览器打开

我需要在webview的页面中通过window.open的方式打开一个链接,但是发现在webview中根本不起作用,通过google发现,想要在js中实现诸如alert窗口,window.open的动作,都得自己写方法来实现,比如alert窗口的话,你需要设置webview的WebUIDelegate,然后在delegate中实现webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:方法便可。
但是window.open找了很多地方都没有一个能行的。
首先有点是很肯定的,就是直接超连接的方式我们可以通过设置webview的WebPolicyDelegate,然后在此delegate中实现webView:decidePolicyForNewWindowAction:request:newFrameName:decisionListener:(针对在新窗口中打开链接的target=”_blank”的情况)或者webView:decidePolicyForNavigationAction:request:frame:decisionListener:(所有的普通链接的加载),实现这些方法,我们就可以控制打开链接的方式,因为我们可以在这里获取请求的url是什么,下面进行什么操作就可以由我们自己来决定了。但是,js中的window.open确实是不调用这些代理方法的。后来终于找到些眉头,我们再次回到WebUIDelegate,发现window.open后,会调用WebUIDelegate中的

- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request;


方法,不过这里接受的request为nil,所以这里无法获取请求的url信息,但是这里你需要返回一个webview的指针,也就是说,在webview中,window.open需要你准备一个新的webview用来处理open的事情。于是就在这里新建一个webview并返回,在返回之前设置好这个新的webview的WebPolicyDelegate方法,然后通过它的

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

在处理url。
下面是简单的代码片段

1
2
3
4
5
6
7
8
9
10
11
12
13
-  (WebView  * )webView : (WebView  * )sender createWebViewWithRequest : ( NSURLRequest  * )request
{

    WebView  *_hiddenWebView = [ [WebView alloc ] init ];
     [_hiddenWebView setPolicyDelegate :self ];
     return _hiddenWebView;
}

-  ( void )webView : (WebView  * )sender decidePolicyForNavigationAction : ( NSDictionary  * )actionInformation request : ( NSURLRequest  * )request frame : (WebFrame  * )frame decisionListener : (id<WebPolicyDecisionListener> )listener  {
    NSLog ( @ "%@", [ [actionInformation objectForKey :WebActionOriginalURLKey ] absoluteString ] );
     [ [ NSWorkspace sharedWorkspace ] openURL : [actionInformation objectForKey :WebActionOriginalURLKey ] ];
     [sender release ];
}
2.WebView的DOM以及innerHTML的操作

这个就比较简单了,直接贴代码,不过实现的方法可以有多种,你可以通过js的方法,也可以通过Cocoa中的DOM对象的方式

1
2
3
DOMDocument  *dom = [ [webView mainFrame ] DOMDocument ];
DOMHTMLElement  *myEle = (DOMHTMLElement  * ) [dom getElementById : @ "mydiv" ];
[myEle setInnerHTML : [ NSString stringWithFormat : @ "%@", @ "blablabla" ] ];
3.WebView的Scroll Position的保存及恢复的方案

这个的解决方法也是有多种的,比如有js的解决方法,基本思路就是通过js来获取当前窗口的scroll position的信息

方案一:JS的方法

比如

1
NSString  *yOffsetString  =  [webView stringByEvaluatingJavaScriptFromString : @ "window.pageYOffset" ];

可以获取y方向的便宜量的字符串格式的值,我们可以将这个值暂存下,到需要使用的时候在设置回去

1
2
[webView stringByEvaluatingJavaScriptFromString :
                       [ NSString stringWithFormat : @ "scroll(0,%@);",yOffsetString ] ];
方案二:NSScrollView的方法

我们看到webview的scrollbar,肯定可以想到webview在某个地方内置了一个NSScrollView的对象。
获取信息

1
2
3
4
NSScrollView  *scrollView  =  [ [ [ [webView mainFrame ] frameView ] documentView ] enclosingScrollView ];
// get the current scroll position of the document view
NSRect scrollViewBounds  =  [ [scrollView contentView ] bounds ];
NSPoint  *scrollPosition =scrollViewBounds.origin;

设置为止

1
2
NSScrollView  *scrollView  =  [ [ [ [webView mainFrame ] frameView ] documentView ] enclosingScrollView ];    
[ [scrollView documentView ] scrollPoint :scrollPosition ];

这样窗口显示的位置就是之前记住的位置了,是不是很简单呢。

碰到问题的时候多用用google和stackoverflow.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值