我有一个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
事件。有没有办法可靠地检测落入“导航到其他页面”存储桶的所有事件?
答案 0 :(得分: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
,用户也点击了链接。我仍然需要广泛地测试解决方案,因为我担心它会导致一些误报。
答案 1 :(得分: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>');"];
}
答案 2 :(得分:1)
您需要添加此行
webView.dataDetectorTypes = UIDataDetectorTypeAll;
然后
- (BOOL)webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType
方法会接到电话。
答案 3 :(得分:0)
我遇到了很多问题。使用UITapGestureRecognizer工作,除了它总是会收到点击,即使是链接。不幸的是,链接在被识别之前有大约300毫秒的延迟,这意味着手势识别器在识别链接之前获得了点击,这会产生时间问题(更糟糕的是因为你不应该硬编码时间等待以防万一Apple改变它)。此外,等待300毫秒以上的点击会给我的应用带来糟糕的用户体验。
所以我最终做的是将一个透明的div叠加在获得非链接点击的所有内容之上。然后,将链接放在更高的z级别。最后,确保所有内容都使用ontouchend="javascript:window.location.href='...';"
。 ontouchend只会按照用户期望的点击发布。设置window.location.href加载一个新页面,确保所有点击调用-webView:shouldStartLoadWithRequest:navigationType:
,我可以检查URL以查看我需要做什么。
HTML看起来像: ... ... ... ...
(我不完全确定“位置:亲戚”是否总是将事物置于同一位置,但它对我的简单页面效果很好;您的里程可能会有所不同。但是,您需要的位置:有序的东西让z-index起作用。)