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

相关推荐
胡萝卜术11 小时前
从API调用到手写LRU:力扣146「LRU缓存」的哈希表+双向链表终极进化之路
前端·javascript·面试
科技道人11 小时前
记录 默认置灰/禁用 app ‘Search Engine Selector‘ 的disable按钮
开发语言·前端·javascript
天疆说11 小时前
Zotero Connector 在 Edge 里找不到桌面 Zotero(Linux / Zotero 9.0.6 / Edge 150)
linux·前端·edge
李伟_Li慢慢13 小时前
02-从硬件说起WebGL
前端·three.js
kyriewen14 小时前
看了微软几万人用AI编程的数据——效率涨24%的代价没人提
前端·ai编程·claude
2601_9637713714 小时前
How to Scale Your WordPress Store Traffic in 2026
前端·php·plugin
亿元程序员14 小时前
老板说我的3D箭头游戏用来做试玩太普通了,没人想玩,让我变点花样...
前端
李伟_Li慢慢14 小时前
01-threejs架构原理-课程简介
前端·three.js
_瑞16 小时前
深入理解 iOS 渲染原理
前端·ios
IT_陈寒16 小时前
SpringBoot自动配置失灵?你可能忘了这个关键注解
前端·人工智能·后端