9

我有一个UIWebView,当用户点击一个链接时我需要做一些事情。有一个委托回调可用于检测水龙头:

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

问题是这段代码不能处理所有的链接点击。例如,一个普通的 Google 搜索结果页面对链接做了一些奇怪的事情:

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

rwt功能导致UIWebViewNavigationTypeLinkClicked点击时链接不会触发事件。有没有办法可靠地检测落入“导航到其他页面”存储桶的所有事件?

4

4 回答 4

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;
}

然后,如果另一个请求来了并且_navigationLeavingCurrentPage是真的,我知道用户已经点击了一个链接,即使导航类型标志是UIWebViewNavigationTypeOther. 我仍然需要对解决方案进行广泛的测试,因为我担心它会导致一些误报。

于 2013-01-18T10:51:13.120 回答
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 中,您可以搜索具有 callback:// url 方案的 NSURLRequest,然后做任何您想做的事情。

这尚未经过测试,但这样的事情可能会让您朝着正确的方向前进。

此外,由于提到了这一点,是的,您可以使用以下方法将自定义脚本添加到任何网页:

- (void)webViewDidFinishLoad:(UIWebView *)webView 
{
    [super webViewDidFinishLoad:webView];    
    [webView stringByEvaluatingJavaScriptFromString:@"document.body.insertAdjacentHTML('BeforeEnd','<script>....</script>');"];
}
于 2013-01-16T19:07:33.113 回答
1

您需要添加此行

webView.dataDetectorTypes = UIDataDetectorTypeAll;

然后

  • (BOOL) webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType

方法将被调用。

于 2016-05-27T11:47:51.040 回答
0

我有很多问题要让它工作。使用 UITapGestureRecognizer 是可行的,只是它总是会收到点击,即使是链接也是如此。不幸的是,链接在被识别之前有大约 300 毫秒的延迟,这意味着手势识别器会在识别链接之前获得点击,这会产生时间问题(更糟糕的是,因为您不应该硬编码时间等待以防万一苹果改变了它)。此外,等待 300 多毫秒的点击时间会给我的应用带来糟糕的用户体验。

所以我最终做的是在所有获得非链接点击的东西之上覆盖一个透明的 div。然后,将链接放在更高的 z 级别。最后,确保一切都使用ontouchend="javascript:window.location.href='...';". ontouchend 只会在点击发布时起作用,这是用户所期望的。设置 window.location.href 会加载一个新页面,确保所有点击都会调用-webView:shouldStartLoadWithRequest:navigationType:,并且我可以检查 URL 以查看需要执行的操作。

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

(我不完全确定“位置:相对”是否总是将事物放在与其他位置相同的位置,但它对我的简单页面很有效;您的里程可能会有所不同。但是,您需要 position:something 才能获得 z -索引工作。)

于 2014-05-14T05:57:28.017 回答