问题描述
|
我想从文件加载html页面,并向其附加一个哈希标签。这可能吗?
我试过了
Nsstring *filePath = [[NSBundle mainBundle] pathForResource:@\"someFile\" ofType:@\"html\"];
NSURL *fileUrl = [NSURL fileURLWithPath:[filePath stringByAppendingFormat:@\"#hashtag\"]];
[self.webView loadRequest:[NSURLRequest requestWithURL:fileUrl]];
NSLog(@\"fileUrl = %@,reachable? %d\",fileUrl,[fileUrl checkResourceIsReachableAndReturnError:nil]);
但这会尝试查找文件someFile.html%23hashtag
,该文件找不到。创建NSURL
对象后,是否可以添加哈希?
我还尝试将文件加载到字符串中并使用loadHTMLString
:
Nsstring *filePath = [[NSBundle mainBundle] pathForResource:@\"someFile\" ofType:@\"html\"];
Nsstring *fileContents = [Nsstring stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
[self.webView loadHTMLString:fileContents baseURL:[NSURL URLWithString:@\"http://someFile.html#hashtag\"]];
在这里,hash标签确实起作用,但是html内的我的javascript引用不起作用。这种方法的一个后续问题是,如何从UIWebView中以字符串形式加载的html中引用javascript文件,即基本url是什么?
我可以想到的一种技巧是将我所有的JavaScript文件直接内联到html中,然后将其作为字符串加载,但是我认为必须有更好的方法!
解决方法
我没有尝试过,但是在没有井号的情况下正常加载文件并用类似这样的方法实现UIWebViewDelegate呢?
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[webView stringByEvaluatingJavaScriptFromString:@\"window.location.href = \'#hashtag\';\"];
}
参考文献:
UIView带您锚定链接
以编程方式滚动到锚点标签
,对于%23问题,我认为Scott Kohlert的替换解决方案不是很好。
以下解决方案似乎更好,我只是从这里复制了它
NSURL *baseUrl = [NSURL fileURLWithPath:stringUrl];
NSURL *fullURL = [NSURL URLWithString:@\"#jumpto\" relativeToURL:baseUrl];
有点离题,我发现iOS 6.0、6.1上的Safari在处理带有锚点的URL方面与iOS 5.1和其他桌面浏览器(包括OSX上的Safari)不同。对于我的某个特定文档,无论是在UIWebview还是iOS 6.0或6.1的iOS上的移动Safari中,首次加载时,页面都不会滚动到正确的位置,重新加载将解决该问题。可能与html的一部分由javascript动态生成这一事实有关。有任何想法吗?
,这就是我在代码中这样做的方式。我将井号标记附加到NSString,然后使用fileURLWithPath将其转换为NSURL。然后,我将%23的所有实例替换为#。所有内容都在下面的代码中进行了说明,但是如果您有任何疑问,请告诉我。
NSString *filePath = [[NSBundle mainBundle] pathForResource:@\"someFile\" ofType:@\"html\"];
NSString *filePathWithHash = [NSString stringWithFormat:@\"%@#yourDesiredHashTagHere\",filePath];
NSURL *theURL = [NSURL fileURLWithPath:filePathWithHash];
//NSURL turns the # into %23 when using fileURLWIthPath. So we need to change it back:
NSString *finalURLString = [[NSString stringWithFormat:@\"%@\",theURL] stringByReplacingOccurrencesOfString:@\"%23\" withString:@\"#\"];
//Then we need to change it back to an NSURL
NSURL *finalURL = [NSURL URLWithString:finalURLString];
//And finally we load this in the webView
[theWebView loadRequest:[NSURLRequest requestWithURL:finalURL]];
,您应该能够拦截NSURLRequest
,将其转换为NSMutableURLRequest
,然后按如下所示更改URL。所有这一切都将在ѭ10中发生。确保设置了UIWebView委托。
- (void) viewDidLoad
{
self.webView.delegate = self;
NSString *filePath = [[NSBundle mainBundle] pathForResource:@\"someFile\" ofType:@\"html\"];
NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
//Make sure the request is mutable
if(![request isKindOfClass:[NSMutableURLRequest class]])
[NSException raise:@\"Need to change the request,but can\'t\" format:@\"\"];
NSMutableURLRequest* mutableRequest = (NSMutableURLRequest*)request;
NSString* newUrl = [NSString stringWithFormat:@\"%@#hashtag\",[[request URL] absoluteString]];
[mutableRequest setURL:[NSURL URLWithString:newUrl]];
return YES;
}
我还没有遇到过请求不可变的任何情况,但是谁知道呢。
或者,您可能想要在原始URL中设置哈希值(就像以前一样),然后用shouldStartLoadWithRequest
中的#
替换第一次出现的%23
。
,@xiang \的答案的补充。如果您正在使用应用程序中的本地html文件,请在swift版本以下:
let urlString = \"relative/path/to/your/index.html\"
let anchorString = \"#your-anchor\"
let baseURL:NSURL? = NSBundle.mainBundle().URLForResource(urlString,withExtension: nil,subdirectory: nil)
if let url:NSURL? = NSURL(string: anchorString,relativeToURL: baseURL) {
// Do something with your URL
}
,我认为您必须在创建文件网址后添加哈希
如果您进行更改,它是否有效?
NSURL *fileUrl = [NSURL fileURLWithPath:[filePath stringByAppendingFormat:@\"#hashtag\"]];
像这样:
NSString *urlString = [[NSURL fileURLWithPath:filePath] absoluteString];
NSURL *fileUrl = [NSURL URLWithString:[urlString stringByAppendingString:@\"#hashtag\"]];
,在Swift中(使用WKWebView):
override func viewDidLoad() {
super.viewDidLoad()
webView.navigationDelegate = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let baseURL = Bundle.main.url(forResource: \"myFile\",withExtension: \"html\") {
//Load the main page and allow access to its directory
webView.loadFileURL(baseURL,allowingReadAccessTo: baseURL.deletingLastPathComponent())
}
}
func webView(_ webView: WKWebView,didFinish navigation: WKNavigation!) {
let anchor = \"#myanchor\"
//Use javascript to jump to the location
webView.evaluateJavaScript(\"location.href = \'\" + anchor + \"\'\",completionHandler: nil)
}