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

Posted

技术标签:

【中文标题】同一页面内的 WKWebview 锚标签不起作用【英文标题】:WKWebview Anchor-tags within same page not woking 【发布时间】:2017-10-03 22:08:04 【问题描述】:

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

问题是点击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>

这就是我在 Obj-C 中创建 WKWebView 并加载 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];

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

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

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

【问题讨论】:

这可能与它无关,但 NSFileHandle 到底是干什么用的? 还有什么可以让你的网络视图与 screen 具有相同的边界??????它存在于您的主视图中,而不是漂浮在屏幕中。 【参考方案1】:

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

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

【讨论】:

【参考方案2】:

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

(稍作测试就会发现您所做的大部分工作,包括 id 和导航委托,都是无关紧要的。错误是我们根本不滚动到内部链接 em>。你应该删掉任何可以删减的内容,以尽可能简单的形式显示问题。)

作为一种解决方法,通过 URLRequest 加载文件:

    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 中修复。

【讨论】:

感谢您的建议。我会尽量删减,然后向 Apple 提交错误报告。 @user899352 请参阅我的答案;如果您使用 URLRequest,您的链接可以正常工作。 这太棒了。我将为最初的问题提交一份错误报告。 此错误已在 iOS 12 中修复。

以上是关于同一页面内的 WKWebview 锚标签不起作用的主要内容,如果未能解决你的问题,请参考以下文章

锚标签在移动设备上不起作用

锚标签href不起作用

锚标签在 iPhone/iPod Touch/iPad 的 Safari (ios) 中不起作用

带有标签的Angular2路由到页面锚点

WKWebView 视口缩小以适应在 iOS 9.3 上不起作用

菜单没有关闭锚标签