美文网首页iOS Developer
神奇的 iOS 11中 UIWebView 页面内锚点失效问题

神奇的 iOS 11中 UIWebView 页面内锚点失效问题

作者: MarkNote | 来源:发表于2017-09-26 19:54 被阅读818次

苹果的每一次升级,都让广大的iOS开发者又爱又恨:一方面,新的API的引入让程序员可以更好的发挥硬件的潜力为用户带来新功能;另一方面,iOS的向后兼容从来不是一件省心的事,以前工作得好好的功能可能就停摆了,或者以前正常的显示,可能在新版本里就错乱了。

这次iOS11的到来也是一样的,我们为新的功能惊喜,也为潜在的问题而忧虑。比如新的模拟器看起来高大上,可以居然不在可以随便设置分辨率。在macbook上都没法为 iPad Pro 12.9' 截屏了!

最近有用户反应MarkNote笔记目录( [TOC])不能跳转。研究了一下发现是<a name=name-of-link>定义的锚点失效了。进一步的研究发现:

  • 不光我的应用存在这个问题,其他凡是在 UIWebView 中加载本地HTML文件或者字符串的应用也一样都存在这个问题;
  • 如果页面是 HTTP/HTTPS协议的则没有问题;
  • 如果页面是 file:/// 协议的则使用<a name=name-of-link>定义的锚点失效;
  • 同样的功能在 iOS 10.3上运行正常;

在UIWebView的事件中设端点发现,点击锚点时还是触发了shouldStartLoadWithRequest 事件,但是 didFailLoadWithError 中没有任何错误。看起来的感觉是, UIWebView 看到是 file:/// 协议的就不理睬锚点的跳转了。

既然如此,看来需要在 shouldStartLoadWithRequest 事件中做文章,注入一段javascript,让锚点滚动到可见区域来。简单的弄了一个方案:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
    if (UIWebViewNavigationTypeLinkClicked == navigationType
        && [@"file" isEqualToString:[[request URL] scheme] ]) {
        NSArray<NSString*>* components = [request.URL.absoluteString componentsSeparatedByString:@"#"];
        if (components.count == 2) {
                NSString* anchor = components.lastObject;
            NSString* code = [NSString stringWithFormat:@"let element = document.getElementsByName(\"%@\")[0]; if (element) {element.scrollIntoView();}", anchor];
                [webView stringByEvaluatingJavaScriptFromString:code];
                return NO;
        }
    }
// 其他逻辑
}

测试通过。准备再测试一下,然后默默的发一个补丁了。

相关文章

网友评论

    本文标题:神奇的 iOS 11中 UIWebView 页面内锚点失效问题

    本文链接:https://www.haomeiwen.com/subject/puwsextx.html