【bug记录10】同一iOS webview页面中相同的两个svg图标出现部分显示或全部不显示的情况

一、问题背景

在vue项目中,同一页面中++直接复制粘贴了两个相同的svg代码嵌入到html中++,

在chrome浏览器中显示良好;

但是在Safari浏览器 或者 iOS WKwebview中,出现++只显示一个svg或者两个都不显示的情况,但是绑定在svg的点击事件仍然可以触发++。

svg的代码如下

html 复制代码
 <svg width="18" height="18" viewBox="0 0 24 24" fill="#212121" xmlns="http://www.w3.org/2000/svg">
          <g clip-path="url(#clip0_3468_29991)">
          <path fill-rule="evenodd" clip-rule="evenodd" d="M6.5 8.69995H4.55C3.55589 8.69995 2.75 9.50584 2.75 10.5V19.4C2.75 20.3941 3.55589 21.2 4.55 21.2H19.45C20.4441 21.2 21.25 20.3941 21.25 19.4V10.5C21.25 9.50584 20.4441 8.69995 19.45 8.69995H17.5V10.5H19.45V19.4H4.55L4.55 10.5H6.5V8.69995Z" />
          <path fill-rule="evenodd" clip-rule="evenodd" d="M11.3634 2.11358C11.7149 1.76211 12.2848 1.76211 12.6362 2.11358L16.9191 6.39642C17.1143 6.59168 17.1143 6.90827 16.9191 7.10353L16.3534 7.66921C16.1581 7.86448 15.8416 7.86448 15.6463 7.66921L11.9998 4.02277L8.3534 7.66921C8.15813 7.86448 7.84155 7.86448 7.64629 7.66921L7.0806 7.10353C6.88534 6.90827 6.88534 6.59168 7.0806 6.39642L11.3634 2.11358Z" />
          <path fill-rule="evenodd" clip-rule="evenodd" d="M12.4001 2.69995C12.6762 2.69995 12.9001 2.92381 12.9001 3.19995V16C12.9001 16.2761 12.6762 16.5 12.4001 16.5H11.6001C11.324 16.5 11.1001 16.2761 11.1001 16V3.19995C11.1001 2.92381 11.324 2.69995 11.6001 2.69995H12.4001Z" />
        </g>
        <defs>
          <clipPath id="clip0_3468_29991">
            <rect width="24" height="24" />
          </clipPath>
        </defs>
 </svg>

二、问题分析

当时由于不清楚原因,svg元素不显示但是可以点击,证明是svg绘制渲染这一步出了问题,即矢量图形没有被正确解析

🌟于是做了两组对照实验:

  • 将两个相同的svg代码,删除其中一份,看是否可以显示【++结果:单一svg在页面中可以显示】++
  • 将两个的svg代码均替换成页面中另一个可以显示的svg,看是否可以显示【++结果:全部替换成如下svg的时候,是可以两个同时正常显示的++】
html 复制代码
 <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
          <path d="M14.9999 4L6.99994 12L14.9999 20" stroke="#212121" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
</svg>

👍根据上述实验分析:

对比新替换的svg代码和原svg代码,可以看出新svg代码最大的不同是没有应用clip-path进行区域裁剪而仅仅是用了path元素绘制。

而原svg单个可以显示、两个则不能显示,猜测可能是++clip-path的id在iOS系统中解析需要局部唯一,否则会造成冲突++。经验证和查询资料,确实如此。

拓展总结

诸如<clipPath>**此类的++图形效果++标签++在用url进行引用时,都需要设置唯一id++**,否则会因为冲突而无法解析效果、从而无法正确渲染矢量图形。

例如:

  • <filter>:滤镜效果
  • <mask>:遮罩效果
  • <linearGradient>和<radialGradient>:渐变和镭射效果
  • <pattern>:使用预定义的图形对一个对象进行填充或描边( 通过fill / stroke属性url引用pattern中预定义的图案)
  • <marker>:定义在<path><line><polyline><polygon> 这些线性/多边形元素上绘制箭头或者多边标记 所使用的图形。(通过 marker-startmarker-midmarker-end 属性将marker中定义的标记附着上来)

三、解决方法

🌰主要有两种思路:

1、避免id冲突

2、避免svg重复嵌入

👍 那么基于上述两种思路,主要有两个解决方法:

1、手动解决id冲突,在页面内保证id唯一【就是自己手动改下id值啦】

2、通过**<use>标签链接svg图形实例,配合<symbol>**定义图形模版对象,避免代码重复。

注意,一个symbol元素本身是不呈现的,通过use引用才显示。

🌰举例

html 复制代码
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
    <symbol id="icon-with-clip" viewBox="0 0 100 100">
        <defs>
            <clipPath id="uniqueClipPath">
                <circle cx="50" cy="50" r="50" />
            </clipPath>
        </defs>
        <rect width="100" height="100" clip-path="url(#uniqueClipPath)" />
    </symbol>
</svg>

<!-- 引入位置1:注意use是放在svg标签中的哦 -->
<svg>
    <use href="#icon-with-clip" />
</svg>


<!-- 引入位置2 -->
<svg>
    <use href="#icon-with-clip" />
</svg>

3、svg不直接嵌入代码,通过**<img>引入**,但是无法直接修改 SVG 图像中的颜色

相关推荐
木叶丸19 小时前
从 Loop 到 Graph:AI 智能体协作系统工程指南
前端·后端·架构
凌云拓界19 小时前
NodeVerdict | 性能门禁:把追踪数据变成 CI 规则
ci/cd·信息可视化·开源·node.js·bug·数据可视化·安全架构
吴懿不在 不负信仰21 小时前
从jQuery谈库与框架的设计之优劣
前端·javascript·jquery
灵析表格21 小时前
灵析表格手机号处理函数深度分析报告
前端·网络·json·wps·灵析表格·excel公式盒子
智海深蓝21 小时前
智慧渔业海上养殖数字孪生实践方向与难点拆解分析
java·前端·网络
丁引21 小时前
《数据清洗的艺术:如何用20行核心逻辑优雅地删除无标签图片》
前端·数据库·python
Bigger21 小时前
Han:一个让 AI Agent 也能做出高级中国风页面的 CSS 设计系统
前端·ai编程·设计
梦想的旅途221 小时前
企业微信自动化:自动发送文本、图片、文件
前端·数据库·microsoft
MartinYeung51 天前
npm爆发大规模供应链攻击 蠕虫污染 2000+ 个包版本: 深度技术剖析
前端·npm·node.js
huabuyu1 天前
治好 AI 长回答的卡、闪、膨胀:渲染开销从 50 万次砍到 1000
前端·javascript