SVG内a锚点链接火狐正常iOS Safari失效如何解决
问题根因
iOS端Safari对SVG命名空间下的<a>标签存在长期未修复的解析bug:默认不会将SVG内的<a>识别为可跳转的HTML超链接,无法触发同页面锚点跳转逻辑,在本地打开HTML的file://协议场景下该问题必现,和页面中写的锚点规则、样式逻辑没有关系。
网上搜来的加xlink:href、加target="_self"之类的偏方都没用:前者是SVG 1.1的废弃语法,新版Safari已经不认了,后者在本地打开文件的场景下根本触发不了跳转。
兼容方案(本地打开页面也可正常生效)
用10行以内的原生JS做事件委托即可,不需要修改原有链接的href配置,也不影响SVG外部普通链接的原有行为,同时适配提供的两种示例场景(普通锚点跳转、锚点触发模态框):
- 不需要改动原有SVG内
<a>标签的href写法,只需要给这类链接加一个统一标记类用于识别 - 在页面底部加一段全局点击监听,识别到SVG内的链接点击时,手动读取href属性完成跳转,绕开Safari的解析bug
修复后的模态框场景完整代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>my title</title> <style> .modal-window { position: fixed; top: 0; right: 0; bottom: 0; left: 0; opacity: 0; pointer-events: none; } .modal-window:target { opacity: 1; pointer-events: auto; } .modal-window > div { max-width: 95vw; max-width: 600px; max-height: 85vh; position: relative; margin: 10% auto; padding: 2rem; background: lightgray; } .modal-close { color: red; line-height: 50px; font-size: 80%; position: absolute; right: 0; text-align: center; top: 0; width: 70px; text-decoration: none; } body { font-size: 32px; height: 100vh; text-align: center; margin: 0; padding: 0; } .for_svg { max-height: 50vh; } </style> </head> <body> <div id="open-modal" class="modal-window"> <div> <a href="#tftyjfjfjhf" title="Close" class="modal-close">×</a> MODAL INFO </div> </div> <div> <a href="#open-modal">link outside svg</a> </div> <div> <svg class="for_svg" viewBox="0 0 400 400" > <rect x="0" y="0" width="400" height="400" style="fill:yellow"/> <a href="#open-modal" class="svg-internal-link"><text x="10%" y="50%">link inside svg</text></a> </svg> </div> <script> // 兼容Safari SVG内链接不跳转的bug document.addEventListener('click', function(e) { const link = e.target.closest('svg a.svg-internal-link'); if (!link) return; e.preventDefault(); window.location.hash = link.getAttribute('href'); }) </script> </body> </html>
- 该方案无任何外部依赖,纯原生JS实现,本地双击打开HTML文件即可正常运行
- 给SVG内链接加
svg-internal-link类是为了精准识别需要兼容的元素,不会干扰页面其他普通链接的逻辑 - 普通锚点跳转场景(第一个最简MWE)只需要给对应SVG内的
<a>加上相同类名,引入这段JS即可正常生效,不需要其他修改
内容的提问来源于stack exchange,提问作者Michaël
相关产品推荐
相关产品推荐

