【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-start、marker-mid 和 marker-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 图像中的颜色

相关推荐
笃行3508 小时前
集中式与分布式,KingbaseES 的四种形态共用一套内核
前端
陈随易9 小时前
Vue 编译器换掉 source map,快了三四成
前端·后端·程序员
ZhengEnCi10 小时前
12 种高级 UI 交互效果及对应 AI 提示词:从按压回弹到底部抽屉的物理感教学
前端·css·交互设计
IT_陈寒13 小时前
Redis大key删除为什么会导致服务卡顿?我的线上事故复盘
前端·人工智能·后端
用户27050777252414 小时前
MCP 最小 Server 实测:3 个 JSON-RPC 报错与修法
前端
用户4993350250714 小时前
一人VIP账号多人共用:Web 代理里的会话共享怎么实现
前端
用户老李14 小时前
无线电自学教程 05:第一台收音机——从矿石机到 SDR
前端
IPIPD14 小时前
Node.js请求遇到503怎么重试?先解析Retry-After,再做有上限退避
前端
葡萄城技术团队14 小时前
dsh-spreadjs-editor 的集成链路:把 SpreadJS Designer 嵌进 Agent 工作台
前端
FlyWIHTSKY15 小时前
vue2和vue3有什么区别,用法上有哪些区别
前端·javascript·vue.js