【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 图像中的颜色

相关推荐
默_笙1 小时前
🔥 让 AI 帮我写完整个 Next.js 博客:框架就是 AI 的"上下文 buff"
前端·javascript
牧艺1 小时前
登录页还在用渐变?我一口气做了 5 个能摸的背景动效:吹蒲公英、滴墨染水、点熔岩闷裂
前端·canvas·交互设计
陆枫Larry1 小时前
状态机简介
前端
陆枫Larry2 小时前
一次登录问题排查:接口没错,错的是旧业务逻辑
前端
小小小小宇2 小时前
大模型打分与采样原理,以及 Pi Agent 核心原理
前端
一位正在转型AI全栈的前端工程师2 小时前
AI 全栈学习之旅 -Week 5:RAG 知识库问答系统:从零到生产级部署的全栈实践总结
前端·python
光影少年3 小时前
react navite 安卓iOS 打包、签名、环境区分
前端·react native·react.js
coderCN3 小时前
Nodejs 第三十四章 数据库(表达式和函数、子查询和连表)
前端·node.js
ssshooter3 小时前
AI 时代你不能不知道的 git worktree
前端·后端·面试
观测云4 小时前
AI时代的用户访问监测:观测云带你身临其境体验用户与前端UI交互旅程
前端·可观测性·观测云·rum