同一页面内的 WKWebview 锚标记不起作用

WKWebview Anchor-tags within same page not woking

我在使用 WKWebView 的 iPhone 应用程序中显示的网页中有许多锚标记。

问题是点击 href 标签并没有将我带到相应的锚点。这在我使用 UIWebView 时可以正常工作,但现在我已经迁移到 WKWebView,它无法正常工作。

我正在按如下方式设置锚标签,努力做到 HTML5 合规:

<a href="#Test1"> Test1. </a>

<h2 id="Test1">

当我在任何浏览器、html 编辑器或 XCode 外部编辑器中显示网页时,锚标记工作正常,但在 WKWebView 中却不行。

这是精简测试 html(尽管它确实有很长的文本字符串):

<!DOCTYPE HTML>
<html>
<head>
    <title> </title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <style type="text/css">     
        .btt {
        font-size: 10pt; 
        color: #000080;
    }
    </style>
</head>
<body>
<h2 id="toc">
    Table of Contents.
</h2>
<ul>
    <li> <a href="#Test1"> Test1. </a> </li>
    <li> <a href="#Test2"> Test2. </a> </li>
    <li> <a href="#Test3"> Test3. </a> </li>
    <li> <a href="#Test4"> Test4. </a> </li>
</ul>
<h2 id="Test1">
    Test1 &nbsp;&nbsp;&nbsp; <a class="btt" href="#toc">Back to Top</a>
</h2>
<p>
    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam 
nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam 
erat, sed diam voluptua. At vero eos et accusam et justo duo dolores 
et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est 
Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur 
sadipscing elitr,  sed diam nonumy eirmod tempor invidunt ut labore 
et dolore magna aliquyam erat, sed diam voluptua. At vero eos et 
accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, 
no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum 
dolor sit amet, consetetur sadipscing elitr,  sed diam nonumy eirmod 
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam 
voluptua. At vero eos et accusam et justo duo dolores et ea rebum. 
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum 
dolor sit amet.

Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse 
molestie consequat, vel illum dolore eu feugiat nulla facilisis at 
vero eros et accumsan et iusto odio dignissim qui blandit praesent 
luptatum zzril delenit augue duis dolore te feugait nulla facilisi. 
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam 
nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat 
volutpat.
</p>
<h2 id="Test2">
    Test2 &nbsp;&nbsp;&nbsp; <a class="btt" href="#toc">Back to Top</a>
</h2>
<p>
    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam 
nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam 
erat, sed diam voluptua. At vero eos et accusam et justo duo dolores 
et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est 
Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur 
sadipscing elitr,  sed diam nonumy eirmod tempor invidunt ut labore 
et dolore magna aliquyam erat, sed diam voluptua. At vero eos et 
accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, 
no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum 
dolor sit amet, consetetur sadipscing elitr,  sed diam nonumy eirmod 
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam 
voluptua. At vero eos et accusam et justo duo dolores et ea rebum. 
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum 
dolor sit amet.

Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse 
molestie consequat, vel illum dolore eu feugiat nulla facilisis at 
vero eros et accumsan et iusto odio dignissim qui blandit praesent 
luptatum zzril delenit augue duis dolore te feugait nulla facilisi. 
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam 
nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat 
volutpat.
</p>
<h2 id="Test3">
    Test3 &nbsp;&nbsp;&nbsp; <a class="btt" href="#toc">Back to Top</a>
</h2>
<p>
    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam 
nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam 
erat, sed diam voluptua. At vero eos et accusam et justo duo dolores 
et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est 
Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur 
sadipscing elitr,  sed diam nonumy eirmod tempor invidunt ut labore 
et dolore magna aliquyam erat, sed diam voluptua. At vero eos et 
accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, 
no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum 
dolor sit amet, consetetur sadipscing elitr,  sed diam nonumy eirmod 
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam 
voluptua. At vero eos et accusam et justo duo dolores et ea rebum. 
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum 
dolor sit amet.

Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse 
molestie consequat, vel illum dolore eu feugiat nulla facilisis at 
vero eros et accumsan et iusto odio dignissim qui blandit praesent 
luptatum zzril delenit augue duis dolore te feugait nulla facilisi. 
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam 
nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat 
volutpat.
</p>
<h2 id="Test4">
    Test4 &nbsp;&nbsp;&nbsp; <a class="btt" href="#toc">Back to Top</a>
</h2>
<p>
    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam 
nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam 
erat, sed diam voluptua. At vero eos et accusam et justo duo dolores 
et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est 
Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur 
sadipscing elitr,  sed diam nonumy eirmod tempor invidunt ut labore 
et dolore magna aliquyam erat, sed diam voluptua. At vero eos et 
accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, 
no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum 
dolor sit amet, consetetur sadipscing elitr,  sed diam nonumy eirmod 
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam 
voluptua. At vero eos et accusam et justo duo dolores et ea rebum. 
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum 
dolor sit amet.

Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse 
molestie consequat, vel illum dolore eu feugiat nulla facilisis at 
vero eros et accumsan et iusto odio dignissim qui blandit praesent 
luptatum zzril delenit augue duis dolore te feugait nulla facilisi. 
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam 
nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat 
volutpat.
</p>
</body>
</html>

这就是我创建 WKWebView 并在 Obj-C 中加载 html 文件的方式:

- (void) viewDidLoad
{
    [super viewDidLoad];
    htmlContent = @"failexample";
    NSString *path = [[NSBundle mainBundle] pathForResource:htmlContent
        ofType:@"html"];
    NSFileHandle *readHandle = [NSFileHandle fileHandleForReadingAtPath:path];
    NSString *htmlString = [[NSString alloc] initWithData:[readHandle readDataToEndOfFile]                          
        encoding:NSUTF8StringEncoding];

    WKWebViewConfiguration *wkWebConfig = [[WKWebViewConfiguration alloc] init];

    webView = [[WKWebView alloc] initWithFrame:[UIScreen mainScreen].bounds 
        configuration:wkWebConfig];
    webView.navigationDelegate = self;
    webView.UIDelegate = self; 
    [webView loadHTMLString:htmlString baseURL:nil];
    [self.view addSubview:webView];
}

我知道点击是在decidePolicyForNavigationAction中处理的:

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction
    decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    if (navigationAction.navigationType == WKNavigationTypeLinkActivated) {
        NSLog(@"Got a click"):
    }
    decisionHandler(WKNavigationActionPolicyAllow);
}

有人知道我做错了什么或者我需要做什么才能让它工作吗?

您的示例在 iOS 10 中运行良好,所以我不得不建议您在 iOS 11 中发现了一个错误。最好的方法是将所有内容打包为一个简单的示例项目和 submit to Apple 作为错误报告。

(稍加测试就会发现您正在做的很多事情,包括 id 和导航委托,都是无关紧要的。错误是我们不会滚动到内部链接 完全。你应该删除任何可以删除的内容,以尽可能简单的形式显示问题。)

作为解决方法,通过 URL请求加载文件:

    let url = Bundle.main.url(forResource: "failexample", withExtension: "html")!
    let req = URLRequest(url: url)
    wv.load(req)

或者,使用本地文件URL:

    let url = Bundle.main.url(forResource: "failexample", withExtension: "html")!
    wv.loadFileURL(url, allowingReadAccessTo: url)

内部链接将起作用。 (但是,此解决方法可能并不总是实用;尽管如此,我仍将此问题视为一个错误,尤其是因为它在 iOS 10 中运行良好。)

更新: 这已在 iOS 12.

中修复

我最近遇到了同样的问题。 html 字符串是从服务器读取的,html 字符串包含许多锚语句 "href = '#XXX' "。锚语句不会先跳转。

解决方案:刚刚注入视口元语句。使用 javascript 动态注入到 html 字符串头部。问题解决了。锚跳得很好。