在我的iPhone应用程序中,我有一个UIWebView,我正在加载一个本地的HTML。一切正常,但现在我想能够处理本地链接(到脚注):当我点击本地链接时,我希望能够跳到它所引用的脚注,然后能够回来。
<a href="#tofootnote">jump to footnote</a>
我通过将我的代码添加到shouldStartLoadWithRequest并拦截本地链接点击来处理此问题;当点击本地链接时,我会运用我的魔法(隐藏一些ui元素,添加后退按钮等等);单击后退按钮会将我跳回到html文档中的原始位置。
问题是单击链接上的ONCE不再调用shouldStartLoadWithRequest。即,以下代码:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSLog(@"foo bar");
return YES;
}
仅显示“foo bar”ONCE(实际上,两次 - 我第一次加载文档时),但之后只有ONCE,无论我点击本地链接多少次
所以,除非有人有更好的解释,否则我猜测UIWebView会缓存文档或链接或其他内容,并且在初始调用后不再调用处理程序;如果是这种情况,我该如何清除此内部缓存? (不重新加载文件)
答案 0 :(得分:14)
我发现这个问题的唯一解决方案是从字符串替换所有锚点 “#anchor”指向被视为URL的内容,例如“| anchor”。这样UIWebView就会认为它是一个真正的链接,并在点击时尝试该请求。这个解决方案显然只有在您自己处理所有点击时才有效,因此可以解释更改后的锚点。我可以理解UIWebView行为的原因,但它相当令人沮丧。委托真的需要消息来匹配onclick等处理程序。
答案 1 :(得分:6)
我可以通过在处理有效的锚点后将window.location
设置为虚拟锚点来解决此问题。
- (BOOL)webView:(UIWebView *)aWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if ([[request URL] fragment]) {
if ([[[request URL] fragment] isEqualToString:@"__DUMMY_ANCHOR"])
return NO;
// Do your custom handling of the anchor here
// Change the location to a non-existent anchor
[aWebView stringByEvaluatingJavaScriptFromString:@"window.location='#__DUMMY_ANCHOR'"];
return NO;
}
}
答案 2 :(得分:1)
当我使用jquery移动嵌入式页面更改遇到此问题时,我发现的一个技巧是在哈希上添加一个随机数。这样iOS似乎认为这是一个新的请求:
//set location hash to path
set: function( path ) {
path += "&" + Math.random();
location.hash = path;
},
这应该通过动态设置onclick事件的路径来实现。
答案 3 :(得分:0)
当我使用onclick =“window.location.hash = ...; return false;”时,这似乎也发生在我身上。而不是捕获点击。
如果我稍微滚动或点击另一个锚点,我可以再次使用该链接。
答案 4 :(得分:0)
如果您使用loadHTMLString加载内容,例如:
[webView loadHTMLString:htmlString baseURL:[[NSBundle mainBundle] bundleURL]];
然后重新加载html-string似乎就足够了。然后单击锚点将(再次)调用您的委托挂钩。
答案 5 :(得分:0)
上述Ben Dolman(工作)代码的变体。它使用两个虚拟链接“重置”UIWebView缓存,以便后续链接仍然可以调用该方法。首先,它将内部链接或片段保存在名为savedFragment的NSString中。然后它告诉UIWebview加载第一个虚拟链接#pageX然后另一个#pageY。最后,它抓取savedFragment并使用它来构造页码,然后在单独的方法中将UIWebview滚动到正确的位置。
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if ([[request URL] fragment]) { //check if fragment exists (treat as internal link)
NSString *fragment = [[request URL] fragment];
//If the fragment is neither "pageX" nor "pageY", treat as an internal link in the PDF
if (![fragment isEqualToString:@"pageX"] &&
![fragment isEqualToString:@"pageY"]) {
savedFragment = fragment; //hold the fragment in savedFragment (NSString)
[pdfWebView stringByEvaluatingJavaScriptFromString:@"window.location='#pageX'"]; //load UIWebView with first dummy link
} else if ([fragment isEqualToString:@"pageX"]) {
[pdfWebView stringByEvaluatingJavaScriptFromString:@"window.location='#pageY'"]; //load UIWebView with second dummy link
} else {
NSString *pageString = [savedFragment stringByReplacingOccurrencesOfString:@"page" withString:@""]; //grab the page from savedFragment
int page = [pageString intValue];
[self scrollWebViewToPage:page-1]; //scroll to page (seperate method)
}
return NO; //do not load any of the dummy links
} else {
return YES; //first load of PDF into UIWebView should be allowed
}
}
答案 6 :(得分:-1)
尝试'触摸'锚标记(将其分配给自身)。我的假设是会导致DOM更新,使其再次检查链接。没有测试过,这只是一个想法!
答案 7 :(得分:-1)
NSURLRequest * request = [NSURLRequest requestWithURL:fileURL cachePolocy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0];
[webView loadRequest:request];