2013-01-16 124 views
9

我有一个UIWebView,我需要做一些事情,当用户点击一个链接。还有可以用于检测水龙头的委托回调:如何可靠地检测到UIWebView中的链接点击?

- (BOOL) webView: (UIWebView*) webView 
    shouldStartLoadWithRequest: (NSURLRequest*) request 
    navigationType: (UIWebViewNavigationType) navigationType 
{ 
    if (navigationType == UIWebViewNavigationTypeLinkClicked) { 
     … 
    } 
} 

的问题是,这个代码不处理所有的链接点击。举个例子,一个普通的谷歌搜索结果页面做一些奇怪的与链接:

<a href="http://example.com/" class="l" onmousedown="return rwt(…)"> 
    <em>Link Text</em> 
</a> 

在挖掘时没有触发UIWebViewNavigationTypeLinkClicked事件的链接rwt作用的结果。有没有办法可靠地检测到“导航到其他页面”存储桶中的所有事件?

回答

6

到目前为止,我在下面的解决方案已经抵达。首先,我注入一些JS代码到网页加载时:

function reportBackToObjectiveC(string) 
{ 
    var iframe = document.createElement("iframe"); 
    iframe.setAttribute("src", "callback://" + string); 
    document.documentElement.appendChild(iframe); 
    iframe.parentNode.removeChild(iframe); 
    iframe = null; 
} 

var links = document.getElementsByTagName("a"); 
for (var i=0; i<links.length; i++) { 
    links[i].addEventListener("click", function() { 
     reportBackToObjectiveC("link-clicked"); 
    }, true); 
} 

当用户点击一个链接,我知道它提前感谢webView:shouldStartLoadWithRequest: navigationType:委托调用:

if ([[[request URL] scheme] isEqualToString:@"callback"]) { 
    [self setNavigationLeavingCurrentPage:YES]; 
    return NO; 
} 

然后,如果还有其他请求到来和​​是真的,我知道用户点击了一个链接,即使导航类型标志是UIWebViewNavigationTypeOther。我仍然需要广泛地测试解决方案,因为恐怕会导致一些误报。

1

我相信这是可以做到,通过在网站的HTML代码中嵌入一个自定义JavaScript将监控的事件,并根据您要监视的事件,它可以触发页面重定向使用自定义URL方案,你可以在shouldStartLoadWithRequest中拦截。

事情是这样的:

<script> 
// Function to capture events 
function captureEvent(el) { 
    window.location.href="callback://"+el.href; 
} 

var elms = document.getElementsByTagName("a"); 
for (var i=0; i<elms.length; i++) { 
    elms[i].addEventListener("onmousedown", function(){captureEvent(el)}, true); 

} 
</script> 

然后在shouldStartLoadWithRequest,您可以搜索的NSURLRequest的有回调:// URL方案,并做你想做的。

这尚未经过测试,但这样的事情可能让你在正确的方向。

而且,由于这所提到的,是的,你可以添加自定义脚本任何网页时,通过使用这样的:

- (void)webViewDidFinishLoad:(UIWebView *)webView 
{ 
    [super webViewDidFinishLoad:webView];  
    [webView stringByEvaluatingJavaScriptFromString:@"document.body.insertAdjacentHTML('BeforeEnd','<script>....</script>');"]; 
} 
+0

我不认为OP有控制在UIWebView中显示的网页。因此他们无法添加自定义JavaScript。 –

+1

您可以在页面加载后轻松添加自定义脚本。查看我的编辑关于如何做到这一点 – Lefteris

+0

非常好的添加如何添加自定义JavaScript到任何页面。 –

0

我有一堆的得到这个工作的问题。使用UITapGestureRecognizer的作品,除了它会一直接收水龙头,即使是链接。不幸的是,链接在被识别之前大约有300毫秒的延迟,这意味着手势识别器在链接被识别之前得到敲击,这产生了计时问题(甚至更糟,因为你不应该硬编码时间来等待以防万一苹果改变它)。此外,等待300多毫秒的点击会给我的应用带来糟糕的用户体验。

所以我落得这样做在覆盖一切,获取非连接水龙头的顶部透明的股利。然后,将链接放在更高的z级别。最后,确保一切都使用ontouchend="javascript:window.location.href='...';"。 ontouchend只会按照用户期望的方式发布。设置window.location.href加载一个新页面,确保所有的水龙头调用-webView:shouldStartLoadWithRequest:navigationType:,我可以检查URL来查看我需要做什么。

HTML看起来像: ... ... ... ...

(我不能完全肯定,如果“位置:亲属”总是将事情在相同的位置,否则,但它很好地工作了我的简单的页面,你的里程可能会有所不同。然而。 ,你会需要的位置:东西以获得z-index的工作)

1

您需要添加此行

webView.dataDetectorTypes = UIDataDetectorTypeAll。

然后

  • (BOOL)webView的:(UIWebView的*)inWeb shouldStartLoadWithRequest:(的NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)法菜单

方法将得到调用。